Documentation
Welcome to the restfb documentation.
Here, you will find basic information on how to use the restfb library. While we cover various topics here, we will only provide an overview of the library’s usage. If you require a more in-depth understanding and additional information, please refer to the cookbook. It contains many recipes that cover advanced usage of restfb.
Migration
Important migration information from 1.x to 2.x
The most important change is the migration to a new JSON parser. With RestFB 2.x we use the very fast minimal-json library. That's the reason why the
JsonObject
and the other objects found in com.restfb.json
have a different API. Please have a look at their GitHub repository to get a sense of how that API looks.
Migration from 2.x to 3.x
The migration from 2.x to 3.x works without major changes in the API. There are some minor changes in the types, but they are all explained in the javadoc.
The biggest change is the Java 8 source level. RestFB 3.0.0 is the first version that needs at least Java 8. You can now use all the fancy Java 8 stuff like streams, lambda functions and so on.
Versioning
At the start of 2022, we decided to switch our versioning scheme for RestFB from pure semantic versioning to calendar versioning. We made this decision to provide developers with a better understanding of when a particular release was made. With the high frequency of changes in the social media space, we felt that it was important to provide more context around each release.
Under our new versioning scheme, the major version number indicates the year of the release, while the minor version number corresponds to the releases within the year.
For example, the 9th release of 2022 would be identified as version 2022.9.0.
We want to assure our users that we will continue to maintain our policy of only making breaking changes to the RestFB API when there is a major position change in the version. This means that such changes will only occur at the turn of the year. This helps to minimize the impact of any changes on existing applications.
Fetching
Important change with Graph API 2.4
fields
parameter to get the fields you need. According to Facebook, reducing the default fields leads to faster performance. In the Advanced Usage section you'll find a example how the fields are requested with RestFB.Fetching Single Objects
The easiest way to get an object from Facebook is to use the fetchObject
method. To use this method, you will need at least the endpoint you want to access and the result type.
The endpoint can be found in the Facebook Graph API Reference. There you will find the correct syntax for the endpoint and how the response json is defined by Facebook. The type you need to provide is a concrete mapping between the json and a java object.
Fetching Multiple Objects
If you want to fetch several objects at once and these objects are very similar, you can use the “multiple ids” request. A simple way to fetch two user objects is a call like:
As you can see, you use the fetchObjects
method and supply a list of ids
as first parameter. You get a JsonObject
as a response with the previously provided ids
as names in this JsonObject
.
If you prefer to work with a strongly-typed object instead of a basic JsonObject
, you can define your own. For example, we fetch the user me
and the page cocacola
. You may even mix different ids. But please pay attention to the fields you request: you may only request intersecting fields, otherwise you will receive an error response.
Additionally, you may work with edges. If all ids
have the requested edge you’ll get the requested data. If one id
is missing this edge, you’ll get an error instead.
The request is equivalent to these requests:
Summary of multiple ids misusage
ids
with non intersecting fields requested: Only intersecting fields are allowed.- Edges are requested that are not part of all
ids
. - More than 50 ids requested: Only 50 ids are allowed in one request.
Multiple ids and the request limit
Although you make only one request, Facebook counts every id. If you provide e.g. 10 ids, the single request is counted as 10.
You should check your implementation: If you have many ids of the same type, a "multiple ids" request can be the better solution. On the other hand, it makes more sense to send single requests if the ids have different types.
Fetching Object Lists
Before we can get to the RestFB implementation details, we have to explain some fundamentals.
Some requests - like a post’s comments or a user’s feed - are returned as a list.
Because these lists can be very large, Facebook provides a paging mechanism. This means
you receive only a limited amount of items encapsulated in a single JSON response (a “page”).
To get access the next page, you have to call a special URL which is provided for you
as part of the page data. You can iterate over all pages by calling these urls.
The relevant field in the paging
JSON is called next
.
Every page includes the data you requested - comments, posts, accounts and so on.
To access this data, you have to iterate over the list on the page. It is important to mention
that there is a limit
query parameter. It limits the elements on one page. Changing the
limit
parameter does not change the overall number of items. You can still iterate over
all pages, but you can change the amount of requests needed for this. For example, if you’d
like to query for a maximum of 50 posts, you should use a counter and stop both loops as soon
as no new items are found or your limit is reached (source code is further below).
RestFB supports paging, but you need to fetch the endpoint with the
special FacebookClient.fetchConnection()
method. One page of a pageable result
set is called a Connection. Now you can iterate over the Connection and you’ll
get a lot of lists of the fetched element. The loading of the next list is
automatically done by RestFB so you don’t need to know how the URLs are built.
Use fields
to change the configuration of the returned objects
Fetching lists of objects supports this technique to specify which
fields should be returned. To get better insight how the fields
parameter can be used,
check out the Advanced Usage section.
A common use case is to fetch all elements of a specific endpoint and work with those items. You can manage this by nested iteration. So you iterate over the connections and iterate over the list in one connection. This sounds a bit complicated, but the following source code example shows how it works.
The Connection
object implements the Iterable
interface.
With this interface it is possible to get an iterator object or you can simply use
the foreach
loop as you can see in the code example above.
We already mentioned the limit
parameter and in the following example we show how to use it
and how you can use a personal limit.
In some rare cases you may need to prevent RestFB from automatically loading further
results and exert deeper control over what the Connection object is doing. To do this, you must
not use the normal iteration process and use a different approach instead. You can
simply work with the very common iterator pattern as mentioned above. Or you can use
the Connection.hasNext()
and Connection.next()
methods on a connection object.
Together with the Connection.getData()
you have complete control over the object.
We don't suggest using this, ...
... because it makes the complete process of fetching items from Facebook unnecessarily complicated and error-prone. Nevertheless, here is a short example of how to use the more complicated way to duplicate the functionality of the first code example in this section.
Fetching Insights
Insights work almost like any other connections, but the Insight
type contains a list of JsonObject
. The reason for this unusual approach is the dynamic nature of the different insights. They returned values are not all of the same structure and
not defined in the Graph API reference.
To fetch some page insights you simply have to call the endpoint of a page. But don’t forget to add the metrics
parameter if you are using Graph API 2.6 or later. An example of this looks like:
Fetching User Picture
Fetching objects with RestFB is straightforward, but there’s a special endpoint that is a bit different and can be a little confusing.
If you call the <userid>/picture
endpoint you don’t receive a JSON response object. This endpoint
redirects directly to the user picture and you get the image’s binary data.
The GET request above returns these header fields.
Now, we want to receive the image url in a JSON instead of the binary data. This can be achieved by adding a special parameter to the request URL. The query parameter is redirect=false
.
The corresponding Java code looks like this:
With this “trick” you receive a JSON response as expected when calling the Facebook Graph endpoint.
Logging
A few words...
Before we go any further, a few words about logging...
With RestFB 2.x the logging framework used is slf4j if found in the class path. If slf4j is not found, java.util.logging
is used as a fallback.
Both types of logging can be used to log the data that's sent over the wire to and from Facebook. It's often helpful to look at the log output to make sure that RestFB is sending the data as expected and that Facebook is returning the correct JSON.
Because RestFB supports the slf4j logging wrapper directly, it is possible to use any logging framework that works with slf4j. Logging RestFB log messages with your favorite logging framework is no problem. You have to change your logging configuration as you do with new project internal loggers.
Logging Example
RestFB tries to use slf4j
. As soon as this logging library is included in the application, RestFB will use slf4j and you can use all the loggings frameworks, that slf4j can use.
If no slf4j is found, RestFB uses java.util.logging
as fallback. Then RestFB works exactly like the older version from the 1.x branch.
RestFB can be forced to use java.util.logging
- simply set the system property com.restfb.forceJUL
to true
. Then slf4j is ignored even though slf4j is on the classpath.
Configuration
To make it easier for developers to configure our logging, we don’t use loggers that are initialised with the name of the class they were created in. Our loggers have fixed names and therefore the logging is clustered into categories.
com.restfb.HTTP
The HTTP logger is used to keep track of the communication between RestFB and the Facebook Graph API. In the log file you'll find the requests/responses, header information and more.
com.restfb.JSON_MAPPER
The JsonMapper
is used to convert JSON to RestFB types. Because the conversion involves many interesting steps, we provide a special logger. When everything is working as it should, the logger is very quiet, but the developer can change the log level to DEBUG
or TRACE
to get much more information about what’s going on during the mapping process. You should only do this if you run into problems and want to trace them back to a specific conversion step.
com.restfb.UTILITY
The logger is used in our utilities. We have utilities for date conversion, base64 calculations and more. Just have a look at com.restfb.util
package. These utilities log some information and use this special logger to not clutter the other logs with less important information.
com.restfb.CLIENT
This logger provides information about the communication between the application and RestFB.
com.restfb.types.CHANGE_VALUE_FACTORY
The log messages in the ChangeValueFactory
are used to inform the developer about some problems with the conversion of an object that is received via a webhook. Maybe RestFB does not support this special value object and the developer can capture the log output to send a special String to the RestFB team. As this is different from the normal logging, we provide a special logger and the developer can filter these messages and log them to a different log file.
As you can see, all loggers use the package structure with the com.restfb.
prefix. This makes it possible to change the log level of all loggers at once.
Searching
With RestFB it is very easy to search Facebook. But before we go deeper in this topic, you need to know some basic information. First, Facebook differentiates between the public search and the targeted search. With the public search, you can search for public information and get some useful insights in what’s going on at Facebook. The targeted search is another approach to filter your private information.
The public search uses a special endpoint called search
. You have to provide a
query string (q
) and a type parameter (type
). With this technique, you’ll get
back data that can be marshaled to the normal RestFB types.
Public search changed on 4 April, 2018
The supported public search types are place
, placetopic
, and ad_*
. Some types like
place
need additional parameters, so you should have a look at the Facebook Graph API Search documentation.
With “targeted search” you are able to search in a user’s home, a.k.a. news feed. You can simply call
the /me/home
endpoint and add the q
parameter as mentioned in
the sections above.
Using FQL
FQL is deprecated and removed with Graph API 2.1
With Graph API 2.1, Facebook discontinued support for FQL (Facebook Query Language). All applications using Graph 2.1 or newer need to change their request and should work with the Graph API.
Because not every kind of request can transferred to Graph API, you should have a look at the Webhooks (former Real-Time Updates).
We support Webhooks with special types and you should look at the Webhooks section in this documentation.
On August 7, 2016 Facebook discontinued support for both Graph API 2.0 and FQL.
Using Webhooks
Basic Webhooks Know-How
The Graph API has supported real time updates for a long time and with Graph API 2.2 the real time updates for
pages have been improved a lot. Since, Graph API 2.5 the real time updates (RTU) have been renamed and are now called
Webhooks
.
Webhooks replace the polling mechanism with a pushing solution. With the deprecation of the FQL API, this is the only way to get notification of changes to your News Feed and other Facebook objects. These changes are very light, so you’ll only get some basic information. But you will get all the important information, and you can fill in the missing information with a normal Graph API call.
Technically, you need to provide an endpoint on a server that Facebook can reach and that understands the JSON-formatted POST
requests that Facebook sends. You can simply parse them using a JSON library or you can use the new webhook
types in RestFB.
For a much deeper insight and a better overview you should take a look at the Facebook explanation of webhooks.
Webhook Types in RestFB
The Webhook types in RestFB are a very special construction. They are fetched differently from other types and while they appear similar on the surface, their internals are completely different. The JSON is pushed to your server and so you cannot use the normal fetchObject
method. You have simply a JSON String and you can now use a JsonMapper
to convert it to a Java object.
The result is a Webhook
entity and you only need to call something like this:
Now you can step through the WebhookObject
and fetch the necessary information. The structure is a bit cumbersome, but RestFB has to reflect the original Facebook JSON structure. In this way, we are able to react to changes much faster and are able to expand our Webhooks support as new possibilities arrive.
The value
-field of the Change
object is very interesting. Here we added a new solution and made use of the @JsonMappingCompleted
annotation in combination with a ChangeValueFactory
.
Because the difference between the WebhookObjects
you receive from Facebook lies in the change value, we implemented a factory so you can work with the correct entity and don’t need to implement some logic. Because some change values contain a postId
, some a photo URL and other specific differences. These are provided by a group of classes whose names end with Value
.
Important notice regarding the new Webhook types
At the moment we only support a subset of all possible webhook JSON types. The main focus lies on the page webhooks. You should be able to use the Webhooks nevertheless, but perhaps you have to deal with the FallBackChangeValue
. It encapsulates the raw JSON that represents the change value and you may work with the JSONObject, but it lacks some convenience methods.
If this happens, you will see a log message with a hint to send us the JSON. We would really like to implement more Value
classes and with the help of our users and the RestFB community we can provide a complete solution for Webhooks.
Webhook made easy
Webhooks are a great feature, but using them is not that easy. The objects have a complex structure and mostly in development the changes
or the MessagingItem
objects are used.
These two object classes are the important objects of every webhook and so we have implemented a helper class that gives developers the opportunity to implement a suitable listener.
The object structure is run through and a callback method is called for each relevant Value
or MessagingItem
object.
So that developers can write a clear class, we have prepared an abstract class that should be used as a basis.
As an example, we would like to react to FeedCommentValue
changes. To do this, we first implement a short class:
Then we register the listener and pass a WebhookObject
. And the listener is already active.
If you want to react to a MessagingItem instead of the changes, the class must be derived from the AbstractWebhookMessagingListener
.
Messenger Platform
See Messenger Platform documentation
With Graph API 2.6, Facebook introduced the Messenger API. The new API allows developers to implement chat bots. With these bots it is possible to provide a great new user experience and the user may contact his/her favorite Facebook pages directly with the messenger.
The implementation of such a bot consists of two elements.
The first element is the webhook. Webhooks are used to receive messages from a user and new JSON requests are sent from Facebook. RestFB supports these new JSON requests and you can find new objects in the webhook packages of the RestFB types. Because the entrypoint to these types is the same as with normal webhooks, you should have a look at the Webhooks section if you need to refresh your knowledge. Otherwise use the webhooks as before and have a short look at the Facebook Messenger Webhook API to understand how they are built.
The second and the more interesting part of the Messenger API is the Send API
. After receiving a text from a user, your bot should react to the request and you can now have different possibilities to respond. The different types are covered in the
following sections, but you have first to know how the Send API is used and how RestFB supports you with the Send API.
Creating a recipient
Sending a message to a user requires a unique recipient identifier. There are three types of identifiers that are supported by the Send API
.
The first is the id
-identifier. You can get the recipient id
as soon as a user sends a message to your bot. Please be aware of the fact that the recipient id
is not the user id. If you try to send a message to a user id
this will not work. You are required to use the recipient id
.
If you received a message and took the id
from that message you can create a new IdMessageRecipient
with this simple line of code:
The second identifier type is the phone number of the user you are attempting to contact. Facebook only sends a message to a phone number if there is a certain level of confidence the the phone number is reachable. Additionally, sending messages to a phone number recipient requires the customer matching feature to be enabled for the app.
Customer Matching requirements and availability
Only bots that belong to a Facebook page with a U.S. based administrator can use the customer matching feature. Phone numbers may belong to users in other countries, too.
You can only send messages as long as the user has not previously opted-out. As soon as she receives the message, a message request is shown and then she can read the message. Afterwards she can decide whether to accept or decline further messages. If the message request is accepted, the bot is allowed to send further messages.
With this small piece of code you can create a phone recipient:
And last, but not least, there is the user_ref
. This reference is fetched from a webhook message and used to create a UserRefMessageRecipient
object. The user_ref
is send to the webhook as soon as the Facebook Checkbox Plugin is used and a user opts-in to receive messages from the website that shows this plugin.
The code to create a UserRefMessageRecipient
is:
Private Replies and the Messenger API
Private replies provide a way to send private messages to a user who created a post or a comment on a Facebook page. So you can start a private conversation from a public “entry point”.
Since September 30, 2019 Facebook allows to use the Send API for private replies. This leads to much better way to communicate with a user and you can use all the cool features the Send API provides.
To use this new way to start the conversation, you simply need the post
or comment
id. With this id you create a recipient object like this:
Then you can use this object as recipient and you are done.
Creating a text message
Now we have a recipient and need something we want to send to the recipient.
The simplest message you can send to a user is the text message. To generate a text
message simply need to generate a Message
object and use the String
constructor.
An example looks like this:
Creating a image message
A Message
object can contain an attachment. A simple attachment is the MediaAttachment
and you only need to provide a URL that points to the attachment and the type of it. Available types are IMAGE
, VIDEO
, AUDIO
and FILE
.
The attachment is then added to the newly-created message. The Message
is created like this:
Use the button template
Facebook allows more complex objects and with these it is possible to define postbacks the user can use.
The postback is a button that is presented to the user in the messenger. On click, a specially-defined string is sent back to the bot via the webhook api so the bot knows which button was pressed.
Like the postback button, there exists a WebButton
. A click on that button directs the user to a webpage.
In this example we create both types of buttons and add them to a Message
.
Use the generic template
A more complex example is the “generic” template.
It may contain some of the so-called “bubbles” that are horizontally-aligned and the user can switch between them. Switching between bubbles is performed by clicking on a arrow at the left or at the right side of the messenger view. Devices with touch support like smartphones can switch between these bubbles by swiping them to the left or right. The arrows are only visible on mouseover, so you should not be confused if you add more than one bubble and don’t see the other bubbles at first glance.
Every Bubble
can contain further information like subtitles and images as well as the buttons
we already saw in the earlier example.
The GenericTemplate
allows a developer to create great-looking messages users can
interact with in very new ways.
Use the media template
With the Messenger Platform 2.2, the new media template type was introduced. This template allows the developer to send a message with animated content like a video or an animated gif. The animation is shown directly in the message thread. Additionally, buttons are available as optional interaction elements.
An example of this template type follows:
If a button is added to the MediaTemplateElement
, the example code looks this:
The MediaTemplateAttachmentElement
is generated with an attachment id and a MediaType
as seen in the example above.
An alternative way to generate the MediaTemplateElement
is the MediaTemplateUrlElement
. A Facebook URL is used to generate the MediaTemplateElement
and only special URLs are allowed. The MediaType
is not needed here, because RestFB detects the type automatically according to the given URL. The allowed URL list follows:
Media Type | Media Source | URL Format |
---|---|---|
Video | Facebook Page | https://business.facebook.com/<PAGE_NAME>/videos/<NUMERIC_ID> |
Video | Facebook Account | https://www.facebook.com/<USERNAME>/videos/<NUMERIC_ID> |
Image | Facebook Page | https://business.facebook.com/<PAGE_NAME>/photos/<NUMERIC_ID> |
Image | Facebook Account | https://www.facebook.com/photo.php?fbid=<NUMERIC_ID> |
Sending a message
Now, we are ready to do the most important thing with our new build objects: sending them to Facebook.
We use the well known publish
method of RestFB and only need to use the right endpoint with the right access token.
To send the message you have to use two parameters, the recipient and the message.
So we are ready to go and do something like this:
Sending a media message
Publishing a message with a media attachment can be solved with a single call. In this explanation we like to send an image to the messenger api. We don’t use an URL as image source and we don’t use a pre-uploaded image.
We show how the very common use case is handled where the application has direct access to the binary data of the particular image. To send the data we use the BinaryAttachment
we already mentioned earlier.
The developer needs to identify the type of the binary file before creating the MediaAttachment
. A good starting point is the MIME type of the file, but this is out of the RestFB scope.
We simply assume, you know what kind of binary data you are publishing to Facebook and you change the MediaAttachment
type accordingly.
In combination with a recipient object a complete call looks like this:
Using the Personas API
See Personas API documentation
The Persona API allows Facebook pages to use virtual persons while sending message with the Send API. With these persons it is possible to show users different contact persons. The contact person has a name an a profile picture. Communication is more personal and users will know who they are talking to, not an abstract company.
Create a new Persona
A Persona
consists of a name, a profile picture and the persona id. While creating a new persona only the name and the profile picture url is needed. As soon as you publish this information to Facebook, you get the persona id. Usually it is the easiest way to use the GraphResponse
type as response object.
Sending messages with a Persona
As soon as a new persona is created, you can use its id in a new message. The id is an additional parameter with the name persona_id
.
Guidelines for Personas
These guidelines are defined on Facebook and are copied here for convenience.
- The
name
of a persona is freeform, but Facebook recommends a first name and last initial, such as “John Z.”. - The page name of the bot will still be included at the top of the thread, even when a persona is invoked. It is not necessary to include the company name in the
name
field. - The persona should not be overly generic.
- The persona should be clearly distinguished from the page/bot itself.
- The persona should not attempt to deceive the user.
- A persona can be created on the fly. It is not necessary to sync one’s entire database of agents to Messenger Platform in advance.
- The total size of the image in
profile_picture_url
may not exceed 8MB.
The welcome screen
Remove the deprecated call_to_actions
from thread_settings
endpoint
thread_settings
endpoint is deprecated and you should remove any configuration you made earlier. In following sections, you will learn the current way to add the greeting text and so on. Use this snippet to clean your bot's welcome screen:
The welcome screen is the first thing a user sees from a Facebook chat bot. On this screen, the user can learn what functionality the bot offers and therefore some basic information about this is presented. The name, profile picture, and cover photo from the Facebook page are shown along with the responsiveness of the bot.
To make it easier for the user to start a conversation with the bot, the developer can use 2 approaches: the “Get Started” button and the Greeting Text.
The Get Started
button
Let’s begin with the “Get Started” button. The button text cannot be changed, but you can define the postback payload. As soon as a user clicks on the button, the payload is sent to the webhook and the chat bot receives the request.
To generate the encapsulated payload, we start with a CallToAction
object. It is initialized with the payload String
. This object is published to the Facebook Graph API. Please see the following example:
The greeting text
The first opportunity to tell a person why the should chat with your bot is the greeting text. You can include a short description of the bot in your greeting text. It can also be used to show a person what the style of your bot is.
To add text, you only need a Greeting
object. This object has several constructors and the simplest way to create the object is a plain String
. This results in a default
greeting text. If you would like to add a locale-specific message, you can add a locale as String
or a Locale
object in the constructor. In the following example you see the construction of a default
text and a text with a en_US
locale. We use the Java Locale
object in the constructor.
Afterwards, you simply publish the Greeting
objects as a list in a Parameter
object to the messenger_profile
endpoint.
Personalize your greeting text
Facebook supports a way to personalize the greeting text. You need to add a placeholder in the text template. There are placeholders for first, last, and full name.
- {{user_first_name}} - user first name
- {{user_last_name}} - user last name
- {{user_full_name}} - user full name
An example greeting text template looks like this:
Simulate typing
Sometimes you need to send a large text to a recipient. Using the messenger platform this can be done in a very small amount of time. Because this is not a natural behavior for a normal user, it is possible to simulate typing so you let the user think she is talking to a human being.
RestFB supports this with a special enum called SenderActionEnum
. In the following example, you can see how the typing simulation can be started.
To stop the typing you can simply use the SenderActionEnum.typing_off
instead.
The SenderActionEnum.mark_seen
action is very interesting. With this, you are able to show the recipient that you’ve read his/her message. This is useful to give the user a good experience and the feeling he/she is talking to a human although it is a bot.
Setting a persistent menu
As of March 2 2017, there is a new persistent menu available. The new menu can contain submenus and allows developers to prevent user interaction via text input. The user may only select items in the menu and the bot does not need to understand the entered text. It seems Facebook tries to support bots that are “dumb”, because these bots cannot react in a useful way to arbitrary text inputs. More sophisticated bots have to understand the text input and act on the input in a way that makes sense.
Back to the persistent menu: the menu can contains several kinds of items. These can be found in the MenuItem
marker interface. A new item type is the NestedButton
. This provides access to the submenu and the NestedButton
can contain a list of call-to-actions.
At the moment, the hierarchy is limited to 3 levels and 5 actions are allowed per level.
The localization feature is very important. A developer can decide, depending on the user’s language, what kind of menu a bot shows and if text input is supported or not.
The following code example is from the Facebook documentation and has been adapted to RestFB and the persistent menu structure. With this, you are able to compare the JSON with the object-oriented approach RestFB provides.
The menu is shown as soon as the user has the en_us
language selected. Then we disable the text input and show 2 buttons,
a WebButton and a NestedButton. The Nestedbutton (“My Account”) is the access point to the underlying submenu with some “account details”. Some PostbackButtons are used to let the user decide what she/he wants to do next: “Pay Bill”, “History” or “Contact Info”.
With these new objects it is possible to build great persistent menus, and the locale feature allows for more advanced user interaction. After creating the menu, you can set it with a simple call to the Graph API:
Pass/Take Thread Control
See Handover protocol documentation
As of Graph API 2.6, Facebook supports the Handover Protocol API. This API is used to allow several applications to work on the Messenger Platform of one page. The primary message receiver can be changed via the API.
For example, you can switch between a chatbot that answers to incoming messages and a human agent who has to take over the conversation as soon as the chatbot is not able to fulfill the request or answer the question. It’s even possible to switch between dedicated chatbots.
To pass the thread control to another app, you can simply use this call:
If the primary receiver app wishes to take back the control, we have to use another request and it will look like this:
Fetch secondary receivers
The primary receiver needs a list of secondary receivers to pass the control to one of them. This list can easily be obtained by calling the Graph API. An example call looks like:
The fields
parameter is optional and can be omitted. In that case, only id
and name
are provided by Facebook. If you need the applications to be prefilled with additional values, you have to add the fields
parameter like in the example above.
Limitations
Facebook does not allow unlimited data to be sent via the Send API and therefore they limit the amount of some fields. RestFB does not limit the data, because they may change in the future and so you don’t have to wait for new relases to use the new limits.
Limitations while creating new messages
- Titles may have up to 45 characters
- Subtitles may have up to 80 characters
- Call-to-action titles may have up to 20 characters
- Call-to-action items may have up to 3 buttons
- A message may have up to 10 bubbles
Messenger Code API
The Messenger Code API is deprecated
Advanced Usage
Metadata & Introspection
The Facebook Graph API provides a great feature which permits deep insight into node data. This feature is called introspection and it works similarly to the well-known reflection techniques that are part of many programming languages.
To activate introspection, you simply need to add the metadata
parameter with the value 1
. How this is done can be found in the Passing Parameters section or look at the example at the bottom of this section.
RestFB supports ths feature, too. All types that extend the FacebookType
have access to the metadata and you simply need to call the getMetadata
method. The returned Metadata
contains all the fields
, connections
and the type
of the requested object.
The type
is very important if you don’t know what kind of node an id
represents. In this metadata field you’ll find the node and you can use this information to send a more complex and type-dependent request to Facebook. For example, if you analyze a feed and its from
fields, it is important to discriminate based on type
because the from
may contain a User
or a Page
.
Passing Parameters
Some requests need additional parameters. With Graph API 2.4 for example it is mandatory to provide the fields
parameter to get a more extensive response. RestFB provides the Parameter
class to serve this purpose.
The Parameter
class needs a name and a value to be sent to Facebook. The value is internally processed by a
json mapper, so you can provide a JsonObject
, a primitive java type (like String
, Boolean
and so on), or a class that uses the @Facebook
annotation (for example the RestFB types or custom ones).
Selecting Specific Fields & Field Expansion
If you fetch a type from Facebook you get a prefilled version. With Graph API 2.4 Facebook changed the behavior and you get only a very minimalistic object. The basic idea of this approach is to save bandwidth and make the transfer much faster, but you have to tell Facebook which fields you need. The requested fields have to be provided as comma separated list.
Basically you should add the fields
parameter on every request. So you can be sure to get
the right information. The fields a type supports can be found in the Graph API Reference.
Request with fields (first level)
A simple example looks like the following snippet. A user is fetched with id
, name
and email
field filled.
Request with fields (limit)
A even more interesting feature is the limit(x)
method. If a type contains a field that
represents a list of other types, for example the comments field on a post, you can limit the transferred
objects with the limit()
. This sounds very complicated and abstract but is very easy to use.
To show the usage we have a simple example.
Request with fields (second level)
Now we go a step further and have a look at the second level of the fields. Until now we worked only with the first level, but Facebook supports more levels. In this example we use the second level. The next level is added with the curly brackets and they encapsulate the fields of the next level type. This sounds complicated too, but is easy as soon as you see a example. And here we go:
Request with fields (third to n-th level)
And the last example is the third level. Now we take the last example and request only the id
from the from
field. This is similar to the second level and so you get a idea how the different levels work and so you can work with n-levels if necessary.
Fetch Post with comments/likes total count
see July 2013 Breaking Changes
To fetch the likes, shares and comments count you must use the correct parameters, because Facebook does not sends you this information with a normal call. In the example at the bottom all fields (shares, comments and likes) are fetched and you see how easy it is to fetch these informations with RestFB.
You need to know how the parameters work, so we dive a bit in this specialty. As soon as you request one of the three candidates you get a short list and you can page through the results, but you don’t get a complete overview. As soon as you add the summary(true)
part - don’t forget the dot delimiter - you get additional fields from Facebook with interesting information. The most important information is the total count. RestFB wraps the summary in the Comments
, Shares
and Likes
type and e.g. the Post
type has the special methods getLikesCount
, getSharesCount
and getCommentsCount
that use the summary.
This explains why you need to add the fields
parameters to the request, otherwise the method returns the fallback value 0
;
As you can see there is a limit(0)
part added to the request. This is simply used to reduce the transferred data. Because no share, comment or like is transferred and only the summary is present. We should support Facebook and don’t request data we don’t use.
Publishing
A note about the Publish and Delete examples below
In order to use these, you'll need to create a Facebook Application and then request an OAuth access token with the proper permissions, e.g. publish_stream,create_event
.
The Facebook Graph API authorization documentation explains how to do this in detail.
If you're in a hurry, though, here's a quick example:
- Create a Facebook Application
- Request
https://graph.facebook.com/oauth/authorize?client_id=MY_API_KEY&redirect_uri=http://www.facebook.com/connect/login_success.html&scope=publish_stream,create_event
- Facebook will redirect you to
http://www.facebook.com/connect/login_success.html?code=MY_VERIFICATION_CODE
- Request
https://graph.facebook.com/oauth/access_token?client_id=MY_API_KEY&redirect_uri=http://www.facebook.com/connect/login_success.html&client_secret=MY_APP_SECRET&code=MY_VERIFICATION_CODE
- Facebook will respond with
access_token=MY_ACCESS_TOKEN
A note regarding the difference between live and dev apps
Newly created Facebook apps are in development mode. These apps work similar to live apps, but some actions act a bit differently. In particular, the publishing of elements is completely different. Even public elements are not visible to other users.
So please check the state of the app if your application behaves strangely or you don't see published elements.
Publishing a Message and Event
In addition from fetching information from Facebook, it is important to be able to write new comments, posts or other kinds of data to Facebook. A popular item is a simple text. Comments, posts, private messages support this type and a developer should have the possibility to easily publish text on Facebook.
Therefore you should have a look at the next example. Here, we create a new Post on the user’s feed. The great message is “RestFB test”. In return, we get the id of the created post. RestFB provides a special type for these returned ids and it is called GraphResponse
.
It is possible to create more sophisticated items. For example, if you’d like to schedule a post, you can simply read over
the next example. In that example, the scheduling timestamp is defined and the created Date
object is used as scheduled_publish_time
. Because scheduled post may not be published before “now”, the published
parameter needs to be false.
Publishing a binary object
Publishing a photo is an example of publishing binary content. There are two ways to publish binary content to Facebook. The old and deprecated way is with an InputStream
and the new way with a ByteArray
. Although the InputStream method is deprecated, you may use it, and we don’t intend to remove it in the near future.
You may use several endpoints to publish a photo and it depends on your use case which one you have to choose. It is important to use the correct access token, because some endpoints have specific permission requirements.
Note regarding publishing multiple photos at once
"There is no way to publish more then one photo in the same graph API call."
(see here in the creating section)The first example shows the InputStream
method. In addition to the binary content, a message is added in the first case and a description in the second one.
This second example shows how to use a BinaryAttachment
with a byte array. The generation of the array is not part of the example code, because it is highly dependent on the libraries used in your project and the way you receive the binary content.
Publishing a binary object with a special field name
Sometimes Facebook requires the form field name to have a special value when sending a binary object, so RestFB provides a mechanism to do this. You can simply use the BinaryAttachment
object. An example for the required field name is adding a caption file to a video. This example is shown in the following code snippet. In that special case, the filename is important too, because it needs to contain the locale of caption file.
The caption file must contain the locale it represents and must be in srt format. In the example above, we set a caption for the en_US
locale and define this as the default locale.
Publishing a tagged Photo
In the previous section focused on publishing a photo. Now we expand on this a bit and include a Tag as part of the publishing process. A tag
permits you to link a Facebook user to a photo, providing formal information about who is in the photo.
To tag a user you need two things. First, a custom PhotoTag
type, and second, you have to modify the request from the
previous section. Because the custom type is the most important and exciting thing, we start with the custom type.
Now we have the custom type and may create a new instance. This is just good old Java. Now, let’s get to the publishing part. To make it easier, we use the publish call from the previous section and simply add the new parameter. When everything is wired together it looks like this:
We use the list in this example because Facebook allows up to 40 tags per photo.
Publishing a video and a thumbnail
We already know how we can publish a single binary file. But RestFB supports publishing several files at once. For example if you like to send a video with a thumbnail.
The main difference is the BinaryAttachment#with(String,String,byte[])
method. In this use case, we have to provide the field name,
because Facebook needs to know where the binary data belongs to. The example uses the source
field for the video and the
thumb
field for the thumbnail.
As a side note: If you send more then one file, you have to support a List
of BinaryAttachments
.
Publishing a Reel video
Similar to various other social networks, Facebook offers its users the capability to upload a distinct form of video content known as ‘Reel.’ In essence, a Reel is a video in MP4 format with a specific aspect ratio of 9:16. This means that it is presented in an upright, portrait-oriented video format, perfectly suited for viewing on mobile devices. One key feature that distinguishes Reels is their duration. Facebook permits Reels to be of a length ranging from 3 to 90 seconds, making them inherently short videos, typically captured using a smartphone camera. This concise and visually engaging format allows users to create and share captivating moments, stories, or messages in a quick and engaging manner.
Facebook introduces a new workflow for developers to publish a Reel using the Graph API. This workflow is divided into three distinct phases:
- Initialize the Upload Session: In this first phase, you will initiate the upload session for the Reel content.
- Upload the Reel: The second phase involves uploading the Reel video to the session established in the previous step.
- Publish the Reel: The final phase is where you publish the Reel to make it accessible to your audience.
This process shares similarities with uploading large files but does have some unique characteristics specific to Reels.
Initialize the upload session
Before you can proceed with publishing a Reel using the Graph API, you must obtain a video upload ID. This unique identifier represents the object in the Facebook graph and serves as the reference for the video content you intend to share.
Once you have the video upload ID, you can proceed to upload the Reel content associated with it. The following code examples assume the use of a Facebook client with a valid page access token. This access token is essential for authenticating your application and gaining the necessary permissions to interact with Facebook’s API.
Upload the Reel
After completing the first phase, you should now have obtained the videoUploadId
. With this identifier in hand, you’re ready to proceed to the video publishing phase. However, it’s important to note that there are two distinct methods for publishing a video on Facebook, and your choice will depend on your specific use case.
The first method involves sending the video as binary data directly to Facebook’s servers. Alternatively, if the video file is hosted on the internet, you can take advantage of a simpler approach by providing the video’s URL.
Upload by URL
In this section, we will begin by exploring the video upload process using a URL. This method is particularly convenient when your video is hosted online and can be easily accessed via a direct link.
Upload by binary data
While one method for publishing a video on Facebook involves providing a URL to the hosted video, an alternative approach is to upload the video as binary data. This method is particularly useful when your video file is not accessible via a URL or when you want to directly transfer the video’s binary content to Facebook’s servers.
Here’s how you can initiate the video upload process by providing the video as binary data:
Publishing the Reel
In the last step of the process, following the successful upload of your video, you have the opportunity to publish the Reel to your page feed. This is where your Reel becomes visible to your audience, allowing them to engage with and enjoy your video content. You can include captions, descriptions, or any additional information to make your Reel more appealing and informative to your viewers. Once published, your Reel will be readily accessible to your audience on your Facebook page:
Additional requests
Another crucial aspect to consider is the request for monitoring the upload status. It’s essential to understand that the video isn’t immediately available for viewing right after the upload process. Before you can publish the video, you should check its processing status. Although you have the option to publish the video as soon as it’s uploaded, the actual publishing is contingent on the video’s processing completion.
The result status field, which is an integral part of the video object, becomes invaluable in this scenario. You can easily access this field, and it provides a limited set of essential information that allows you to monitor the video’s processing progress before making it available for your audience.
Publishing a Checkin
Publishing a checkin works like publishing a normal post to a user’s feed. You simply have to provide a place
parameter with a place id
. If you only have longitude and latitude, you have to search for places in the given area first and let the user select the correct place. Publishing via longitude/latitude is not possible since Graph API version 2.0. (see Stackoverflow question)
Publishing a Video Via Resumable Upload
Uploading a short video is the same as uploading a picture. You should take a look at the picture section to understand how it works.
A new feature Facebook added with Graph API 2.4 is resumable upload support. Large videos (up to a file size of about 2GB) should be uploaded with this new approach. The current max value can be found in the Graph API documentation, or you can simply try to start the upload and handle any filesize errors that occur.
The resumable upload is divided in 3 phases: Start, Transfer, and Finish. If you are familiar with databases and transactions, you can compare the start with starting a transaction and finish with committing it. The transfer phase is where the real action takes place.
The Start
Phase
The first phase is the Start phase. Instead of uploading the file itself, you tell Facebook you want to upload a file and how big it is. The file size you send to Facebook is in bytes. Facebook checks the size and returns an error if something is not okay, but normally you should get a Video ID, a Session ID, and the range of bytes (expressed as a start and end offset) Facebook expects you to send in the first transfer chunk.
The Transfer
Phase
From Facebook’s response, you’ll know what the first chunk of the file you need to upload is. Now you enter the Transfer phase. You upload a chunk of the file the same way you normally upload a binary file to Facebook - you simply have to add some additional information about the offset and session so Facebook can join the file correctly.
With each chunk transfer, Facebook will return the next byte range it’s expecting. This happens in a loop. So you upload the next part and get new offsets, and upload those bytes and so on.
At some point you’ll receive a response where start and end byte offsets are equal. This signifies that it’s time to enter the Finish phase.
The Finish
Phase
After uploading all binary chunks you enter the third phase and send Facebook the request to publish the video. The
response is the frequently-used “success” JSON and you may use the GraphResponse
type to easily access
the success
field.
After you receive a success response, you’ll have to wait until Facebook finishes processing the video. This might take a few minutes. Once done, you’ll receive one or more notifications: an email, a Facebook message, and - if you have a working real time update subscription - a call regarding the new video.
Once you receive a notification, the video is online and ready to be played.
Deleting
To delete an object on Facebook, RestFB provides a deleteObject
-method. You have to provide
the ID of the object and RestFB does the magic. As a return value you receive a boolean - true
means the object had been deleted, false
otherwise. You might encounter one of the common exceptions
if something happened.
Batch API
Batch requests allow to send many requests to the Graph API in one HTTP call. If the requests are independent, Facebook will execute them in parallel. Then you can save time and speed up requests. Are the requests dependent, this means that in one requests data from another part of the batch request is used, then Facebook executes these calls sequentially.
Overall batch requests can speed up requests or make them easier. Depending on the use case and the used requests.
Limitations of batch request
A batch is limited to 50 requests.
In a batch requests, you can define which HTTP requests type you like to simulate, then you can add headers per call and special bodies, too. If you like to publish binary data to the Graph API, this is possible.
RestFB provides a builder to generate the necessary JSON. But it is important for the user to have a basic knowledge of the batch requests and the special responses. In the following section you’ll learn how the builder is used, how a request is built and how you can work with the response afterwards.
Deeper insights to the batch requests, that are not handled here, can be found in the Facebook documentation.
Using Batch Request API
RestFB supports you sending BatchRequest
objects. Therefore we have implemented the BatchRequestBuilder
.
Our builder provides several settings and you can configure the BatchRequest
with a fluent interface.
To build a minimal request, you only need to provide a relative path. If you like to request the me
resource, you can do it this way.
Sometimes it is necessary to provide some additional query parameters for the request. For example if you like to fetch only some specific fields you can use the builder, too.
Sending data to Facebook is as easy as fetching data. You only have to change the request method and provide some data you like to send in the body. The code looks similar to this.
Since you know how to create a BatchRequest
you only need to send the request to the Graph API. RestFB provides a special method for this. Overall the complete requests is defined in the following way.
After receiving a bunch of BatchResponse
objects, you can convert the data contained in the body using the RestFB JsonMapper. Of course you need to know, what kind of object Facebook sends to you in advance, to let everything work correctly.
In case of the request is containing a list instead of a single object, you can use the Connection
object that is provided by RestFB.
Last but not least there is another special information you need to know. Maybe a request runs into an error you can simple access the http code of that part by using the getCode
method of the BatchResponse
object.
Including Binary Attachments Using the Batch Request API
Sometimes you like to send binary data with a BatchRequest
. The way this is expected by Facebook is also supported by RestFB. First you need to define a file identifier. This is a link between the request and the attachments.
The identifier is added to a batch request with the attachedFiles
method. If you like to add more then one file in a request, you can add a list of identifier as comma sperated list.
Additional to the batch requests you have to create a list of BinaryAttachment
. The single BinaryAttachments
needs the former used identifier to do the mapping between the binary data and the BatchRequest.
After creating the requests and the list of binary attachments you can simply send the data with the executeBatch
method. The complete procedure as java code looks like this.
Dependencies between operations in one request
A special usage of the batch requests are dependent requests. These requests are put in one batch, but you can for example use the result of the first request in the second request and receive the complete result. The requests are executed sequentially on the Facebook servers.
We like to show you an example that is ported from the Facebook reference to RestFB. First you have to define the request to fetch the friends. The request is named, so it can be used in a second request as we see later on.
Now we use the result of that request in the second request we define in the next code snippet. It is important to know, that access to the first result set is done with a JSONPath expression. The complete requests will look like this.
Now you can send both requests to Facebook as we did in the sections above.
Access Token Operations
Get Login Dialog URL
Before you can build your Facebook Login Dialog URL you need to look deeper into the the scope concept. Every Access Token is bound to a scope and a scope is a set of permissions. The developer decides which permissions are needed to get the application working correctly.
RestFB supports the developer building the scope and so you should use the ScopeBuilder
. The permissions are implemented as Enums. Here’s an example how to build a scope:
With the ScopeBuilder you can now easily build the login dialog url, like this:
Extending an Access Token
Normally access tokens are only valid for a short time, but you can extend the lifetime with a simple Facebook call. RestFB provides a method to make this easy.
Getting an Application Access Token
App access tokens are used to make server-to-server calls on behalf of your application. These special access tokens allow you to modify your application settings and make some other calls - for example, publishing Open Graph actions or debugging access tokens.
To obtain an Application Access Token, you’ll need your App ID and App Secret. For this reason, Application Access Tokens are only used for server-to-server communication.
RestFB provides a mechanism to obtain application access tokens. All you need to do is make the following call:
Getting an Device Access Token
Important change with Graph API 2.6
With the Device Access Token, Facebook provides functionality to connect to devices with limited input or display capabilities.
The device access token is generated using a two-step process. First, you have to call FacebookClient.fetchDeviceCode
(see example code). You receive a user code, a code and some additional information. The user code has to be shown to the user and she has to enter it on a special Facebook page. The url of that page is part of the DeviceCode object. You should not hard code this url, because Facebook might change it. As soon as you present this information to the user, you have to poll Facebook and try to fetch the device access token.
Fetching the Device Access Token
With Graph API 2.6, Facebook changed the way a device token is requested. First we need a special access token that consists of the application id
and the client token
. The client token can be found in the Application Dashboard. The new token looks like <app_id>|<client_token>
. With this access token, a new FacebookClient
is created and the client is used for the device token interactions with Facebook. Because the application id is part of the access token we don’t need to provide the application id in the method call. So we have two new methods that work with this access token and don’t use the application id as parameter.
The first part - fetching the DeviceCode
- looks like this:
Now we have to call the polling call in a loop and can receive the same exceptions as in earlier versions. One change is important: there is no FacebookDeviceTokenDeclinedException
because this information is not sent to the application. This is an important change, because you have to handle this in your application. You can run into the code expired exception or you let the user close a dialog or something and stop the polling in respect to the user action.
The polling call doesn’t need the application id, so it looks like this:
The checked device token exception
The polling method should return the AccessToken, but may throw a FacebookDeviceAccessToken exception.
FacebookDeviceTokenPendingException
You showed the user_code
to the user and he/she had not finished the authorisation. This is a rather normal case because you should poll Facebook in short intervals and the user cannot switch devices (for example) that quickly.
FacebookDeviceTokenDeclinedException - (only up to Graph API 2.5)
The user declined the authorisation and your application is not allowed to access Facebook on behalf of that user.
FacebookDeviceTokenCodeExpiredException
Everything workd fine, but the authorisation process took to long. Perhaps you showed the user_token
to the user and he/she did not start the authorisation. Anyway, it is not possible to finish the process and you have to start again from the beginning.
FacebookDeviceTokenSlowdownException
You started the polling and the polling interval is too small, so you were polling too fast. Make the interval larger and spend more time waiting between 2 polling requests. The DeviceCode
object contains the interval facebook expects. You should respect this.
Security Operations
Parsing Signed Requests
Parsing Deauthorization Callback request
A user may uninstall an application in his or her Facebook app settings. Because the application owner might need this information, Facebook calls a Deauthorization Callback. A developer can set the deauthorization callback url in the app settings. As soon as someone uninstalls the app, this url is called with a signed POST request.
RestFB provides support for checking these signed requests and decoding the provided information.
The following snippet explains how to use the DeAuth
type to get the user id of the user who
uninstalled the app. Additionally, you’ll get the date when the app was uninstalled.
Securing Graph API Requests
Most requests need an access token. If someone is able to steal the access token, he or she can send spam with this app.
To make this more secure, Facebook provides a special parameter called appsecret_proof
. This is a parameter that is
transferred as query parameter in a normal request and contains a hashed version of the app secret.
The additional security is only achievable if the communication to Facebook occurs via a
server controlled by the developer.
The FacebookClient
contains the obtainAppSecretProof
method to calculate the proof,
but a much easier way is to instantiate the DefaultFacebookClient
with the additional
appsecret_proof
parameter. In that case, the appsecret_proof
is automatically added to every call.
Require proof on all API calls
appsecret_proof
to be transferred.
If this option is enabled, all calls without a proof result in an exception.Use access token as header field
For a long time RestFB used the access token only as query parameter and this was the only way to do authenticated Graph API calls. For security reasons this is not the best way, because query parameters are most of the time logged in proxy servers and many other appliances.
Facebook supports another mechanism and so it is possible to provide the access token as HTTP header information. This is part of the oauth specification and RestFB allows the developer to enable this way to transport the access tokens to Facebook, too.
By default, RestFB still uses the query parameter, but you can change this using this flag on the DefaultFacebookClient
object like shown in this code:
Please keep in mind, that this feature is not tested in every aspect and with every possible call. So please provide us information if you run into problems with the mechanism.
Facebook supports for a long time the connection between a Facebook business page and a Instagram business account. With this connection a business or creator can use an Facebook app to manager their presence on Instagram.
The API can be used to get and publish (only for partners in the beta progam) their media, manage and reply to comments on their media, identify media where they have been @mentioned by other Instagram users, find hashtagged media.
This API cannot be used for consumers.
Find the Instagram id
First you need an access token with the manage_pages
and the instagram_basic
permissions. With those permissions it is possible to fetch the needed page access token including the instagram id. For this we simply call:
Now you have a list of pages, containing the page access token and the instagram account id.
Show user profile
After fetching the instagram id that is connected to the facebook business page, you can use that id to fetch your instagram profile information.
With the page access token containing the instagram_basic
permission, we create a
FacebookClient
and then we can fetch the profile. The profile itself is returned as IgUser
type.
In this example we define the field list before the call. Adding the fields explicitly to the call allows us to have a better control over the returned object.
List media
The most important elements, you can start with when using the instagram api, are the IgMedia
objects. Because we now know how to access the profile, we can access the media list with a similar call. But in this case we have to use a Connection
object, because the data is returned as a list with paging.
With this snippet, we get a list of IgMedia
objects with almost completely filled objects.
Disable/Enable media comments
Despite from fetching instagram media objects and the connected comments, it is very interesting to manage the comments. Managing comments is not only answering and sending text, but handle the problems in this area, too.
So a simple solution to stop a flood of comments is to disable or enable the comment function for a media object completely.
To use this function, you first need a media id. You can get one via webhook or while fetching the profiles media list. Then you simply need to make a special request and the comments are disabled.
To re-enable the comments again, the call is almost the same. The only difference is the boolean value. Instead of false
it is simply true
. And the call looks like this.
Then the comments are enabled again.
Writing a comment
The most important action on a media object is writing comments using the Graph API. The used page access token needs the instagram_manage_comments
permission.
You need the media id to access the comments endpoint and on this you can create new comments. The call look like this.
Instagram comments are all text. The only way to visually enhance the text are emojis.
With the introduction of the WhatsApp Business Platform, Facebook now also allows WhatsApp to be used via the API. Specifically, there are currently two APIs to use WhatsApp. On the one hand the Cloud API and on the other hand the On-Premises API.
RestFB supports the Cloud API and covers both the communication with the WhatsApp Graph API and the conversion of the incoming Whatsapp Webhook messages.
WhatsApp Business Platform Client
The easiest way for developers to use the WhatsApp Business Platform is to create a RestFB Client based on the DefaultFacebookClient
.
However, communication with the WhatsApp Business Platform differs from communication with the Facebook Graph API in one important respect. The access token must not simply be passed as a query parameter, but must be passed as an HTTP header field. WhatsApp Business Platform only accepts this method, so we created the ability to easily toggle the behavior.
The class method is called setHeaderAuthorization
. An example code for switching the behavior and sending an object then looks like this:
Running The Examples
RestFB provides a repository on Github with an example project. In this repository RestFB is used to fetch several pieces of information from Facebook, publish some information, and run a legacy example. The whole project is Maven-based and you may use this repository to start your own project using RestFB.
To run the examples you need to download the restfb-examples project as zip file or clone it from Github. Don’t forget to replace the MY_ACCESS_TOKEN
with your access token, otherwise the examples won’t run.
Supported Graph Object Types
RestFB can map JSON to any class that has fields annotated with the @Facebook
annotation, which is discussed in more detail in the JSON Mapping Rules section.
However, for your convenience, all basic Graph API Object types have their own Java implementation in the com.restfb.types
package.
You may use these builtin types if you wish, or you can subclass them to add additional fields or functionality, or just write your own if you have special requirements. The builtins come with reflective implementations of toString()
, hashCode()
, and equals(Object o)
to make your life simpler. If you subclass any of the builtins and add additional fields with accessors, those fields will be automatically taken into account by the above 3 methods.
In the com.restfb.types
package you can find many classes and some packages. The classes represent Graph API types that are used in the “normal” Graph API. The distinction between normal and other classes is really easy if you look at the packages. The Marketing API has its own package called ads
. Everything that is only used in the Marketing API can be found in this special package.
The webhook
and send
packages are associated with each other. Everything is located in the webhook package
that is received via a Facebook webhook. Changes to the feed, changes to the user and page and of course incoming messages are received by subscribing to the Messenger Platform webhook.
The send
package contains all objects that are used by the Messenger Platform to send new messages to a user. The different templates (even the airplane specific ones), quick replies and so on can be found here. How they are used is explained in the Messenger Platform section of this documentation
So all Graph API types that don’t belong to the Marketing API, the Messenger Platform or the Facebook Webhooks are “normal” Graph API types and can be found in com.restfb.types
.
Working with JSON
Per the architecture of RestFB, a JSON mapper is used to convert the Facebook JSON into Java objects and convert them afterwards in the RestFB types according to defined rules.
RestFB 2.x uses a slightly modified minimal-json to map the JSON, because it is not only an implementation that has rather small code base, but it is a fast mapper. Moreover, the minimal-json code is completely covered by junit tests.
Mapping Rules
Using DefaultJsonMapper
,
RestFB is able to recursively map JSON fields annotated with @Facebook
to the following Java types out of the box:
- The convenience classes provided by RestFB in
com.restfb.types
String
Integer
Boolean
Long
Double
Float
java.util.Date
Enum
BigInteger
BigDecimal
Optional
Connection
- Your own JavaBean-compliant classes
Don’t forget to provide a public default constructor! List
s of any of the above typesMap
as key-value store withString
keys
For example:
The special Enum handling
Important to know when defining your own enums is the internal handling of enums in the RestFB JSON mapper. Normally the mapper tries to convert the given string from the Facebook JSON to a constant name of the enum that has the exact spelling.
Since most Facebook enums don't match the official Java enum conditions, RestFB provides a fallback and tries to convert the value to uppercase and create the enum from it.
There are three ways to define your enums:
- use the exact name as Facebook does
- use uppercase as Java expects
- use a custom mapping using the `@Facebook` annotation
Java to JSON mapping
Java to JSON mapping is supported by default via JsonMapper.toJson(Object object)
. You may recursively convert primitive wrapper types as specified above, List
s, Map
s with String
keys, and your own Javabean types by applying the @Facebook
annotation to any fields you’d like to include in the conversion.
The Connection
type is handled different and completely ignored in the Java to JSON conversion.
Additionally the Optional
type will return the value in the JSON.
The default behavior of DefaultJsonMapper
is to throw a FacebookJsonMappingException
if it cannot map JSON to Java correctly. However, given the frequency with which the Facebook API changes, you might want to guard yourself from “surprise” errors in production by exerting more fine-grained control over how the mapper handles mapping exceptions. You can do so like this:
A note about Java to JSON mapping with the Graph API
As-is, DefaultJsonMapper
should meet the needs of the vast majority of users. If it doesn’t support a feature you need, you can easily subclass it or write your own implementation of JsonMapper
instead.
Getting Any Kind of Data as a JSON Object
Sometimes you can’t know field names at compile time
so the @Facebook
annotation can’t be used.
Or maybe you’d like full control over the data that gets returned.
Either way, RestFB has you covered. Just map any API call to JsonObject
.
JsonObject
is the lowest-level object type. You have full control over the
object, but you don’t have convenient type mapping support available. For example, date fields
are just Strings
and you have to map them manually to a Date
object. The version
independence regarding the Graph API is gone, too. You should only work
with the JsonObject
if you know what you are doing.
Fetching a single object is almost the same as with a standard RestFB type. You simply
choose the JsonObject as returned type and you are ready to go. Afterwards you can
use the JsonObject
API.
The JsonObject API used by RestFB
Since RestFB 2.x the internally-used JsonObject
implementation is based on the
minimal-json library. In our benchmarks, this implementation
is really fast.
If you’d like to use a JsonObject
in a Connection, there are two ways you can go.
The first was is to simply use the JsonObject
as the returned type and work
with fetchConnection
as described in the Fetching Object List section.
The second way is even more low-level and you only work with the JSON returned by Facebook. You should have a good understanding of the returned JSON in order to access the fields. The example below shows how to do this:
Using the low-level JsonObject
is sometimes OK, but perhaps you’d like to map the object
or special fields to RestFB types. You can manually invoke the built-in JsonMapper
to do this.
Error Handling
All FacebookClient
methods may throw FacebookException
, which is an unchecked exception as of RestFB 1.6.
These are the FacebookException
subclasses that you may catch:
-
FacebookJsonMappingException
Thrown when an error occurs when attempting to map Facebook API response JSON to a Java object. It usually indicates that you’ve used the
@Facebook
annotation on a field with an unsupported type or the Facebook API JSON doesn’t map correctly to the fields you’ve annotated (e.g. attempting to map a JSON string to a JavaBigDecimal
or a JSON object to a JavaList
).You generally should not explicitly catch this exception in your code, as it usually signifies programmer error in setting up
@Facebook
annotations. One valid use for catching this exception, however, is to detect when Facebook changes what an API call returns on their end, which would break your live code. It may be useful to catch this exception and then send a notification to you or your ops team to notify them that your application needs to be updated. -
FacebookNetworkException
Thrown when a failure occurs at the network level. This can happen if your machine doesn't have a network connection or the Facebook API endpoint returns an unexpected HTTP status code. If there's an HTTP status code available, it's included in the exception so you may take custom actions depending on what type of error occurred.
-
FacebookGraphException
Thrown when the Graph API returns an error, as shown in the example JSON snippet below. Exposes the
type
andmessage
so you can handle them in your code and take custom action as needed.Note that
FacebookGraphException
is a catchall Graph API exception. For your convenience, RestFB will throw more-specific subclassesFacebookOAuthException
andFacebookQueryParseException
if it detects either of these Graph API error types. These are described below. -
FacebookOAuthException
Thrown when the Graph API returns an OAuth-related error (type
OAuthException
orOAuthAccessTokenException
), as shown in the example JSON snippet below. -
FacebookQueryParseException
Thrown when the Graph API returns an FQL query parsing error (type
QueryParseException
), as shown in the example JSON snippet below. -
FacebookResponseStatusException
This is thrown by RestFB when an FQL call fails.
FacebookGraphException
and its subclasses are not applicable in that case because Facebook returns this “legacy” exception instead due to FQL not yet being a full-fledged member of the Graph API.FacebookResponseStatusException
will include both the error code and error message returned by the Facebook API so you may take custom actions depending on the type of error that occurred. -
FacebookResponseContentException
This is thrown by RestFB when Facebook responds with unexpected data. For example, when extending an access token, Facebook should return an HTTP response body of the form
access_token=123&expires=456
. But if Facebook does not respond as expected - perhaps they modify the response format in some future API release -FacebookResponseContentException
will be thrown.It is unlikely that you will ever see this exception.
Here’s some example code to illustrate the above. Keep in mind that your code doesn’t need to handle every single exception the way we’re doing here - this is just to demonstrate what’s possible.
Here’s some example code to illustrate the above. Keep in mind that your code doesn’t need to handle every single exception the way we’re doing here - this is just to demonstrate what’s possible.
Rate Limiting
To prevent abuse of the Graph API, Facebook uses a rate limiting mechanism.
The number of calls you are allowed to make depends on the kind of request. There
are 3 types of limits: app limit
, user limit
and page limit
.
The app limit is tied to the app. As soon as you hit this limit, you are in trouble. because you will not be able to make any more calls using this Facebook app. This is a limit that affects all of your users and Pages.
The user limit comes into play when you use a user access token. This limit can can be reached when a user sends too many requests to Facebook. If you reach this limit, the application can be used by other users and the application limit will not be triggered. by other users and the app limit will not be triggered. The user will have to wait before new requests can be sent.
The page limit is a bit different and more complicated. This limit is reached if a page access token is used to send too many requests to Facebook. But the page limit is directly connected to the page and not to the application. If any application that manages a page triggers the limit, all applications that use a page access token for this page are in trouble. In the past, Facebook has permitted the app owner to send an increase request to enlarge the limit for the page. Now they are using an opaque algorithm to detect a suitable limit.
RestFB supports the limits and you can get the limit information from the WebRequestor
. The WebRequestor
provides
a DebugHeaderInfo
with rate limiting and some additional debug information Facebook provides per call and
developers can process this information and act according to the limits given.
In general, the rate limits are not provided until you reach an 80% threshold. Once you are above this limit, the
request will include the rate limit and you can reduce your calls.
The DebugHeaderInfo
can be fetched after every client call like this:
The example above shows only a short sample and you can get more information. Very important for opening new bug reports on Facebook is the trace id. A complete explanation of the returned header fields can be found here.
Extensibility and Unit Testing
In addition to FacebookClient
, RestFB provides default implementations for WebRequestor
and JsonMapper
, two components that DefaultFacebookClient
depends on to do its work.
These dependencies are designed to allow for straightforward subclassing (if you just want to replace a little functionality) and simple custom implementations (if you need full control).
This comes in handy when unit testing - for example, you can write your own WebRequestor
implementation that simulates a Facebook API endpoint response. You can drop in custom data designed to exercise your application’s Facebook integration or simulate error conditions to make sure you’re handling them properly.
Here’s a trivial example which shows one way you might implement this:
Boost Performance
Generating a SimpleDateFormat
instance is incredibly expensive and you should not generate a new formatter for every date string you have to parse. Therefore RestFB provides the possibility to replace the old and slow parsing with a faster solution. But you have to take care of some cleanup because the higher speed can result in a small memory leak. Of course RestFB provides everything you need to do it right.
With version 1.7.0 you can decide which DateFormatStrategy
you use. The default strategy is the SimpleDateFormatStrategy
. It’s almost the same behavior as in the versions before 1.7.0 and you don’t need to change anything.
The faster strategy is called CachedDateFormatStrategy
. You have to set this manually in the DateUtils
singleton and call the clearThreadLocal
method at the end of a thread to prevent the memory leak mentioned above. You should have a look at the code example below.
Because we provide the DateFormatStrategy
as an interface you can implement your own strategy.
ETag support
You can improve your connection’s performance by using the ETagWebRequestor
. This WebRequestor is a special implementation wich adds ETag support to the restfb’s requests. For further information about ETag
you should have a look at the wikipedia page.
With the EtagWebRequestor
the response body of every single request is stored in a cache. If you send the same request again to the Graph API, a hash key is added to the request header. Facebook will check the hash key and if the new response is the same as the stored one, Facebook returns an HTTP 304 and RestFB uses the cached response body. If an HTTP 200 is received instead, the old cached response body is replaced with the newly received response.
With this Requestor
you can cut down on a lot of network traffic and it is very easy to use. This snippet shows how the EtagWebRequestor
is created and used in RestFB.
Disable Caching while using EtagWebRequestor
Sometimes it is useful to switch to the non-caching version. The EtagWebRequestor
provides the isUseCache
and setUseCache
methods. With these methods you can ask the Requestor if caching is enabled and switch it to your needs.
Possible problems
- Because every call is stored in the cache, this may lead to a performance degredation if the cache size increases significantly.
- The cache uses a
SoftHashMap
to store the response bodies. If you drive your system to the memory limit, the JVM will remove elements from the cache to allow the system to work normally. If this happens at a really bad time, RestFB may run into problems and you will have to re-try your request.
It is possible to use another inner Map
implementation. We have a static method to change the implementation before the ETagWebRequestor
is initiated.
Afterwards you can use the webRequestor
as shown above.
Links
Visit RestFB’s home on Github.
Have a question not covered here? Ask in the RestFB Google Group.
Found a bug or have an enhancement request? Create a ticket in the issue tracker.
Download a read-only copy of the current source code using Git: