The Facebook Business SDK is a one-stop shop to help our partners better serve their businesses. Partners are using multiple Facebook API's to serve the needs of their clients. Adopting all these API's and keeping them up to date across the various platforms can be time consuming and ultimately prohibitive. For this reason Facebook has developed the Business SDK bundling many of its APIs into one SDK to ease implementation and upkeep. The Business SDK is an upgraded version of the Marketing API SDK that includes the Marketing API as well as many Facebook APIs from different platforms such as Pages, Business Manager, Instagram, etc.
facebook-java-business-sdk
is a Java library that provides an interface
between your Java application and Facebook's
Graph API. This
tutorial covers the basics, including examples, needed to use the SDK.
Business SDK Getting Started Guide
To get started with the SDK, you must have an app registered on developers.facebook.com.
To manage the Marketing API, please visit your App Dashboard and add the Marketing API product to your app.
IMPORTANT: For security, it is recommended that you turn on 'App Secret Proof for Server API calls' in your app's Settings->Advanced page.
When someone connects with an app using Facebook Login and approves the request for permissions, the app obtains an access token that provides temporary, secure access to Facebook APIs.
An access token is an opaque string that identifies a User, app, or Page.
For example, to access the Marketing API, you need to generate a User access token for your app and ask for the ads_management
permission; to access Pages API, you need to generate a Page access token for your app and ask for the manage_page
permission.
Refer to our Access Token Guide to learn more.
For now, we can use the Graph Explorer to get an access token.
To start using Java SDK, follow the instructions on Getting started instruction.
If you want to use pre-compiled .jar file, visit https://repo1.maven.org/maven2/com/facebook/business/sdk/facebook-java-business-sdk/ to download specific version. If you download the one without dependencies, you will need to download all dependent .jar files and add them to your path when build and run. Use the .pom file in the version directory to decide dependencies.
Here is the minimal code needed to create a campaign in your ad account. If your app and build environments are set up correctly, this code should compile and run without error. You can verify the created campaign in Ads Manager.
import com.facebook.ads.sdk.APIContext;
import com.facebook.ads.sdk.AdAccount;
import com.facebook.ads.sdk.AdAccount.EnumCampaignStatus;
import com.facebook.ads.sdk.AdAccount.EnumCampaignObjective;
import com.facebook.ads.sdk.Campaign;
import com.facebook.ads.sdk.APIException;
public class QuickStartExample {
public static final String ACCESS_TOKEN = "[Your access token]";
public static final Long ACCOUNT_ID = [Your account ID];
public static final String APP_SECRET = "[Your app secret]";
public static final APIContext context = new APIContext(ACCESS_TOKEN, APP_SECRET);
public static void main(String[] args) {
try {
AdAccount account = new AdAccount(ACCOUNT_ID, context);
Campaign campaign = account.createCampaign()
.setName("Java SDK Test Campaign")
.setObjective(Campaign.EnumObjective.VALUE_LINK_CLICKS)
.setSpendCap(10000L)
.setStatus(Campaign.EnumStatus.VALUE_PAUSED)
.execute();
System.out.println(campaign.fetch());
} catch (APIException e) {
e.printStackTrace();
}
}
}
More examples can be found in the /examples
folder.
To locally modify this package and use the updated package in your project, please follow these steps:
- Clone or download the source code and import it into your favorite IDE
- Make the necessary modifications
- Remove the maven-gpg-plugin defined in the
pom.xml
- Build the modified package and install it in the local Maven repository by executing the following Maven command
mvn clean install
. A JAR file will be created and installed in your local directory (typically located in the.m2
folder). - Update your project's
pom.xml
to reference the locally modified version of the package in case you changed the business SDK package version - Build your own project and test
Please see the Business SDK Documentation for more information about implementation and common scenarios. The Business SDK is consistent with v3.0 endpoints related to Pages, Business Manager, Instagram and Marketing products. Please refer to APIs within the Business SDK to get the list of APIs that are within the Business SDK.
You always need to create an APIContext before making any API calls. APIContext includes your access token and app secret:
APIContext context = new APIContext(ACCESS_TOKEN, APP_SECRET);
To fetch a campaign object:
Campaign campaign = new Campaign(CAMPAIGN_ID, context); // this only creates a new empty object
campaign = campaign.get().requestAllFields().execute();
// 1. get() is the API call name to get the object;
// 2. requestAllFields() means you want all the fields. If you only want certain fields, then you can call requestXXXFields() instead, and sever response will only contain specified fields.
// 3. ***IMPORTANT*** any API calls should end with execute(), otherwise it will not be executed.
Or, you can use an equivalent shortcut:
Campaign campaign = Campaign.fetchById(CAMPAIGN_ID, context);
After fetching the object, you can read the data inside:
String id = campaign.getFieldId();
String name = campaign.getFieldName();
// Note that the methods to read field data are getFieldXXX(). This is to distinguish method names of field data from method names of API GET calls.
Update:
campaign.update()
.setName("Updated Java SDK Test Campaign") // set parameter for the API call
.execute();
Delete:
campaign.delete().execute();
Edge is a relational concept in Graph API.
For example, if you want to know all the campaigns under an ad account, then you call GET on the campaigns
edge from the ad account object.
Or, if you want to create a new campaign under this account, then you call POST (create) on the campaigns
edge of ad account.
AdAccount account = new AdAccount(ACCOUNT_ID, context);
APINodeList<Campaign> campaigns = account.getCampaigns().requestAllFields().execute();
for(Campaign campaign : campaigns) {
System.out.println(campaign.getFieldName());
}
** Important **: Handling pagination:
Most edge APIs have default pagination, which returns a limited number of objects (~30 objects) instead of the entire list. If you want to load more, you need to make a separate API call. In our SDK, you can call to nextPage()
:
campaigns = campaigns.nextPage();
- Or, enable auto pagination iterator with:
campaigns = campaigns.withAutoPaginationIterator(true);
In this case, campaigns.iterator() will return an iterator that can fetch the next page automatically.
// Enhanced for loop
for(Campaign campaign : campaigns) {
System.out.println(campaign.getFieldName());
}
// Foreach with lambda is also supported
campaigns.forEach(campaign -> System.out.println(campaign.getFieldName()));
// Note: APIException will be wrapped in a Runtime exception
To fetch all campaigns in your account.
With auto pagination iterator, next page will be fetched automatically in enhanced for loop and foreach loop. In this scenario, campaign.size(), campaign.get(i)
is no longer reliable and shouldn't be used
Most objects are under ad account. So you may always want to try account.createXXX() to create an object.
AdAccount account = new AdAccount(ACCOUNT_ID, context);
Campaign campaign = account.createCampaign()
.setName("Java SDK Test Campaign")
.setObjective(Campaign.EnumObjective.VALUE_LINK_CLICKS)
.setSpendCap(10000L)
.setStatus(Campaign.EnumStatus.VALUE_PAUSED)
.execute();
// The create call only returns id of the new object.
// So you want to fetch() to get all the data of the object.
// fetch() is just another shortcut for
// campaign = campaign.get().requestAllFields().execute();
campaign.fetch();
Every execute() is an HTTP request, which takes a network round trip. Facebook API does support batch mode, which allows you to make multiple API calls in a single HTTP request.
In this SDK, you can simply replace execute() with addToBatch() to prepare a batch API call. When it's ready, you call batch.execute().
Example:
BatchRequest batch = new BatchRequest(context);
account.createCampaign()
.setName("Java SDK Batch Test Campaign")
.setObjective(Campaign.EnumObjective.VALUE_LINK_CLICKS)
.setSpendCap(10000L)
.setStatus(Campaign.EnumStatus.VALUE_PAUSED)
.addToBatch(batch, "campaignRequest");
account.createAdSet()
.setName("Java SDK Batch Test AdSet")
.setCampaignId("{result=campaignRequest:$.id}")
.setStatus(AdSet.EnumStatus.VALUE_PAUSED)
.setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
.setDailyBudget(1000L)
.setBidAmount(100L)
.setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_IMPRESSIONS)
.setTargeting(targeting)
.addToBatch(batch, "adsetRequest");
account.createAdImage()
.addUploadFile("file", imageFile)
.addToBatch(batch, "imageRequest");
account.createAdCreative()
.setTitle("Java SDK Batch Test Creative")
.setBody("Java SDK Batch Test Creative")
.setImageHash("{result=imageRequest:$.images.*.hash}")
.setLinkUrl("www.facebook.com")
.setObjectUrl("www.facebook.com")
.addToBatch(batch, "creativeRequest");
account.createAd()
.setName("Java SDK Batch Test ad")
.setAdsetId("{result=adsetRequest:$.id}")
.setCreative("{creative_id:{result=creativeRequest:$.id}}")
.setStatus("PAUSED")
.setBidAmount(100L)
.addToBatch(batch);
List<APIResponse> responses = batch.execute();
// responses contains the result of each API call in order. However, if the API calls have dependency, then some result could be null.
Currently all the errors are wrapped in APIException
and its subclasses.
MalformedResponseException
is caused by the improper parsing of a server response (likely a bug in the SDK).
FailedRequestException
is caused by either a client error or server failure. See details in the next section.
We have a plan to improve this by adding more details and providing a convenient function to get the error code.
You can enable the debug output by setting the APIContext to debug mode:
public static final APIContext context = new APIContext(ACCESS_TOKEN, APP_SECRET).enableDebug(true).setLogger(System.out);
This will print out the network requests and responses. By default it prints on STDOUT, but you can customize by calling .setLogger(PrintSteam)
In v0.2.0, we added APIRequest.changeRequestExecutor(IRequestExecutor), which can be used to set your own network request executor. This makes it possible to add proxy settings, automatic retry, or better network traffic management. See /example/NetworkCustomizationExample.java
.
Currently this is a static method because it is likely to be a global setting. If you do think object-level Customization is needed, we'll add that functionality.
The executor needs to implement IRequestExecutor
interface:
public static interface IRequestExecutor {
public String execute(String method, String apiUrl, Map<String, Object> allParams, APIContext context) throws APIException, IOException;
public String sendGet(String apiUrl, Map<String, Object> allParams, APIContext context) throws APIException, IOException;
public String sendPost(String apiUrl, Map<String, Object> allParams, APIContext context) throws APIException, IOException;
public String sendDelete(String apiUrl, Map<String, Object> allParams, APIContext context) throws APIException, IOException;
}
DefaultRequestExecutor
is used by default, and it is also a good starting point for Customization.
It is recommended to use setXXX() or requestXXXField() to construct a proper APIRequest, which prevents mis-spelling of parameter/field names. However, if you believe that some needed params/fields are missing from these methods, you can call:
APIRequest.setParam(param, value)
APIRequest.setParam.requestField(field, true)
This also works if you believe the type of the param is not correct in SDK.
In this case, please help us make improvement by filing issues.
If you believe that certain fields are returned from server, but they are missing in class definition, then you can still access those fields by fetching it from raw response:
campaign.getRawResponseAsJsonObject().get("field").getAsString();
This situation can occasionally happen if new fields are added to serve response while SDK is not up-to-date. We'll update the SDK periodically to include new fields.
Most of Marketing API can be found in SDK classes. If you don't find the one you want to access, it is possible to construct an Ad-hoc APIRequest:
APIRequest<AdAccount> request = new APIRequest<AdAccount>(context, "me", "/adaccounts", "GET", AdAccount.getParser());
APINodeList<AdAccount> accounts = (APINodeList<AdAccount>)(request.execute());
When constructing the APIRequest, you need to provide
- APIContext, which has the access token,
- The node ID, which is typically a long number, but it can also be some alias, like "me",
- The edge name, which should start with "/"; if it's for a Node API, then use "/"
- The HTTP Method, GET/POST/DELETE
- The parser for the expected response type. You can use null if it is not in the SDK, which will return APINodeList when executed.
There are many possible causes for a failed request:
- Incorrect parameters are provided in the API request (check Graph API Docs)
- Permission issue (check your access token or app secret)
- SDK bug (report on Github)
- Temporary network issue (check your network and retry)
- Temporary server issue (retry, or report on Facebook Platform Bugs if it happens too often)
- Server bug (report on Facebook Platform Bugs)
As the first step of troubleshooting, please enable debugging in the APIContext.
Here are some hints on troubleshooting:
- If it's caused by incorrect parameters, you'll see error descriptions in the exception message.
- If it's caused by permission issue, you'll see error message like "permission denied" or "unknown path"
- If in stack trace you see that the failed request is caused by exceptions such as NullPointerException or MalformedResponseException, it is likely a SDK bug (or your own bug, depending on the stacktrace).
- If you see in the debug message that the params sent to server don't match what you specified, it is possible that you didn't specify the param correctly, or SDK didn't assemble the request properly.
- For temporary server issue, typically retry should work after a few seconds.
- If server persistently responds with "Unknown error," then it is potentially server bug.
Our SDK is autogenerated from SDK Codegen. If you want to learn more about how our SDK code is generated, please check this repository.
Facebook Business SDK for Java is licensed under the LICENSE file in the root directory of this source tree.
facebook-java-business-sdk's People
Forkers
hailg hanishi propahard82 pasqualej alicemmm pkdevboxy xardazz facebook2react eric23 hindol faisalbasra djebbibmw david04 mohamedmaalej momentfeedinc onealtang kleopatra999 manhlamt maczam kaiyuanliu ctaylors duplicatedcode frednold lsandrade stepanovdg jiangzhuolin fzheng nemccarthy paintmagazine-venmo sang-d bitsmuggler mw138 aleksabl adssetsab hanangi emoswa chrisptang fengwuze iron-heisenberg stingerhouse runt18 ganeshkannusamy who tvhung83 kogitant amjaliks a395604019 jerry80409 tangkuo tituskeuler ryoinoue robsoncassol bryant1410 tuanbaros saulg igustafson hideo-jung perundurai-products scootz69 isitinschi gac1 jpvelsamy snandasena ellorah tupans mamunhossen hello100blog umeshkt oooliviaaa diplomadrs adam8989 derskeal zammot zammottomate tommaz ladaidong jp-gc darrenfu globalcherry-group nikhilw tahermirza1 sdougherty1 ezy023 surajsahoo immensitas-archived huangdehui2013 murple13 tawawhite inpowered noureddinez lopatosvetlana tmihalicka creativewebmatrixsolutions teukureynaldoo baytelman opportunitylivetv atyhieu russel2002 ddinh-adobe moisestgfacebook-java-business-sdk's Issues
ClassCastException in weblogic - APIRequest.java
Please use HttpURLConnection instead of HttpsURLConnection. This is giving ClassCastException in weblogic. Working fine when I changed to HttpURLConnection .
You should never explicitly import/use Sun Java SE implementation specific classes in your code.
Link to similar issue:
http://stackoverflow.com/questions/3038026/using-java-class-httpsurlconnection
v2.5 Class APIRequestCreateAdVideo#setVideoFileChunk(String) parameter type error
As title. The method's parameter type should be java.io.File not java.lang.String. As my understand is not correct, please correct me, thanks.
Sample Code Not Working
Sample code to create a campaign listed on the main Code page on Github, doesn't work. Sample code within the Examples folder for QuickStartExample, doesn't work.
Does anyone have any working sample code to get this working?
The library depends on gson version 2.5:
You should consider testing it with more versions - maybe 2 versions (so apps that use a different version of gson). For us it's not an issue.
Your pom should specify which versions are acceptable.
e.g.:
[2.4,2.5]
This is low priority from our end (since it does not collides) but might be an issue for an app that is using gson on different version then 2.5
Use a single Gson instance
It looks like all of the objects in com.facebook.ads.sdk.* have the same static, synchronized method for constructing the Gson object:
synchronized /*package*/ static Gson getGson() {
if (gson != null) {
return gson;
} else {
gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC)
.excludeFieldsWithModifiers(Modifier.PROTECTED)
.disableHtmlEscaping()
.create();
}
return gson;
}
Gson instances are threadsafe, and therefore a single instance could be shared throughout the codebase. Maybe the APIContext can grow a method for getting the Gson instance? It would also make it easier for consumers to override the defaults.
how to get pagination for adhoc request
Hi team,
Just have a question, how does pagination work for cases like below:
APIResponse res = new APIRequest<APINode>(context, "", "search", "GET").execute(params);
Please advise.
Thanks,
Sang
java 1.7 support?
Hi, it seems like current package only supports java 1.8+, while some of our exists projects are using 1.7 or older. It requires a lot of extra works to upgrade all our projects to java 1.8. Would you plan to support java1.7 in the future?
AdsInsights Object is Missing Fields.
Reference https://developers.facebook.com/docs/marketing-api/reference/ads-insights. The AdInsights Object is missing the estimated_ad_recall_rate and objective fields
Documentation for detailed targeting.
I was unable to find enums or documentation on targeting adverts on Facebook.
For eg: "setFieldGenders( )" takes a list of long as an arguments but its not clear which number corresponds to which gender, can you point me to a documentation which I can refer for these cases?
Thanks in advance.
Pushkar
AdSet.requestAllFields() doesn't return name
APINodeList return non-null object after calling nextPage() with zero items
Is it normal?, I just did follow the examples of how to paginate but instead of using campaigns I used adinsights. For now I check the size of the node list to end the loop.
Thanks.
Cannot get tabs from user/account
Hi,
In the previous version, I could get pages' tabs from ConnectionObject node.
In 2.6, I couldn't get this object from account (page) node, as it throws exception:
" Requires either an app access token, or a page access token for this Page"
Is that intended feature? I'm able to get promotable_posts from this node, so just want to double check.
Thanks.
User user = new User(fbUserId, context);
APINodeList<APINode> accountList = user.getAccounts()
.requestField("id")
.requestField("name")
.requestField("promotable_posts")
//.requestField("tabs") //require page accesstoken
.requestField("picture").execute();
Upload progress (v2.5)
When upload the video, we want to show upload progress bar, so how to get the progress percent from FaceBook?
AdsInsights's bug
0.4.0 AdsInsights can not get all breakdown data "age","country","gender","impression_device" and other.
Audience Insights Query - Access Token/Required Scope
https://developers.facebook.com/docs/graph-api/reference/audience-insights-query/
How do I access this via my app? Would I have to request ads_management? read_insights? ads_read?
Reasons for supporting EnumOptimizationGoal 'Clicks' in AdSet
Hi there
Why do you support OptimizationGoal 'Clicks' in AdSet (EnumOptimizationGoal)? This feature isn't supported by the facebook api since version 2.4.
@SerializedName("CLICKS")
VALUE_CLICKS("CLICKS")
If it's a failure, I will create a PR.
Thanks in advance.
Kind regards, Patrick
Move IRequestExecutor to APIContext
APIRequest delegates to IRequestExecutor to make all HTTP calls; currently a default implementation is used and stored in a static field in APIRequest, with static methods which can be used to override it.
This makes it awkward for testing, as you then have global state you need to setup and teardown, which also precludes parallelizing test runs. It also makes it impossible to use different IRequestExecutors for different kinds of requests without synchronization or some sort of coordination (admittedly I don't have a use case for this).
Wouldn't it make more sense for the IRequestExecutor configuration to live somewhere else, for example APIContext?
AdAccount.fetch() throws FailedRequestException
Hello,
My application receives FailedRequestException exception, when it tries to AdAccount.fetch()
Exception: com.facebook.ads.sdk.APIException$FailedRequestException: {"error":{"message":"(#100) Tried accessing nonexisting field (last_used_time) on node type (AdAccount)","type":"OAuthException","code":100,"fbtrace_id":"GHeibz8E4TY"}}
at com.facebook.ads.sdk.APIRequest.readResponse(APIRequest.java:223)
at com.facebook.ads.sdk.APIRequest.access$100(APIRequest.java:44)
at com.facebook.ads.sdk.APIRequest$DefaultRequestExecutor.sendGet(APIRequest.java:344)
at com.facebook.ads.sdk.APIRequest$DefaultRequestExecutor.execute(APIRequest.java:322)
at com.facebook.ads.sdk.APIRequest.executeInternal(APIRequest.java:157)
at com.facebook.ads.sdk.AdAccount$APIRequestGet.execute(AdAccount.java:12225)
at com.facebook.ads.sdk.AdAccount$APIRequestGet.execute(AdAccount.java:12220)
at com.facebook.ads.sdk.AdAccount.fetchById(AdAccount.java:187)
at com.facebook.ads.sdk.AdAccount.fetch(AdAccount.java:173)
It seems that facebook changed schema, and now they are not returning 'last_used_time' field
java SDK should be changed accordingly.
Thanks,
How to get audience_size of specific audience name ?
I have a set of audiences name, but not audience id.
How can I get the size of each audience, audience type and audience id.
Example: I have exactly name of audience: "Design Engineer". I want to get audience type is "work_positions", audience id is "109542932398298" and audience size is "105197"
Thanks !
autocomplete search
Hi,
Does the SDK support autocomplete search for targeting objects such as (location, locale..)
I was trying to use APIRequestGetTargetingSearch class, but couldn't execute on AdAccount Node.
Basically I'm trying to build query like this: search?q=un&type=adgeolocation
Please let me know if I misunderstanding about this functionality.
Thanks,
Add optional retry for transient errors.
I get a decent amount of transient errors while calling the Facebook api. Immediate retries of the same request work. It would be nice to add retry support into the sdk, possibly in APIRequest.callInternal(). The response has the is_transient field in it, if this is true it would be nice if the sdks retried instead of all calling clients to have to catch the APIException, check if it it is transient and then retry everywhere a request is made. Making this optional by adding a boolean (retry) with the number of retry attempts to the APIContext would allow for users to turn retries on or off.
Exception from sdks:
com.facebook.ads.sdk.APIException: {"error":{"message":"An unexpected error has occurred. Please retry your request later.","type":"OAuthException","is_transient":true,"code":2,"fbtrace_id":"DAbvR5wiN2d"}}
Put user limitation
Hi
i try to put 'madid'( Android advertising ID) to custom audience.
and i want to know limitation of user's data.
if i had tried to put 30000 data,
i got {"error":{"code":1,"message":"An unknown error occurred","error_subcode":99}}
so could you let me know limitation of added user.
NullPointerException throws while trying to access /me/businesses
Hi ,
I'm using java sdk v0.4. It seems like there has no method to allow me to list all businesses belongs to the user. So I just use the following code as alternative:
APIRequest<Business> request = new APIRequest<Business>(context, "me", "/businesses", "GET",Business.getParser());
The API response correctly as expect:
{"data":[{"name":"Alibaba advertising","id":"7349984ACCOUNTID72"}],"paging":{"next":"https://graph.facebook.com/v2.8/130101310692072/businesses?access_token=MY_ACCESS_TOKEN&limit=25&offset=25&__after_id=enc_AdCRaZCZAD9ZAbIQDB7lYwCoNqAaNcqRbEWaRPZCHaPS8eSxQ11pUw7nHnOC1ZCBGm6moP4vaYSOp3D132M032XHZBUG3P"}}
But this line of code throws a NullPointerException which I think it shouldn't:
JsonObject paging = obj.get("paging").getAsJsonObject().get("cursors").getAsJsonObject();
The above code can be found at Business.java, line 163.
Would you be kindly to take a look? Thanks a lot.
-Peng
VideoUtils.waitForVideoEncoding does not handle failure correctly
VideoUtils.waitForVideoEncoding will continue retrying even when the call to getVideoStatus indicates that there was an error (it only ever checks if the status is "ready"). It should probably instead return false or throw an exception.
Ajax error is not formatted correctly
Currently, ajax error message is:
responseText: "{"success":false, "code": 13, "message": "{"error":{"message":"Invalid parameter","type":"OAuthException","code":100,"error_data":{"blame_field_specs":[["daily_budget"]]},"error_subcode":1885272,"is_transient":false,"error_user_title":"Your Budget Is Too Low","error_user_msg":"The minimum budget for this ad set is $19.90.","fbtrace_id":"B8zThZN6jAv"}}"}"
Which cannot parse by JSON.
The correct one should be: (removing the double quote around responseText.message
{"success":false, "code": 13, "message": {"error":{"message":"Invalid parameter","type":"OAuthException","code":100,"error_data":{"blame_field_specs":[["daily_budget"]]},"error_subcode":1885272,"is_transient":false,"error_user_title":"Your Budget Is Too Low","error_user_msg":"The minimum budget for this ad set is $19.90.","fbtrace_id":"B8zThZN6jAv"}}}
Retrieve Saved Audience
Use slf4j for logging
The package currently uses a PrintStream instance for logging. IMO it would be better to use slf4j, which gives consumers control over which logging framework is used, how logging is done, finer grained control over which kinds of messages are logged, etc.
Stream-based video upload API
It would be nice if VideoUtils exposed a stream-based API for uploading videos, as opposed to only offering a File based one as it does now. This can be achieved with a minor refactoring of the existing code, where the File-based methods delegate to a stream-based one.
Should we also support async API?
Hi, I think that a lot of Java/Scala developers would love to use this project. So should we support them with an Async API? For example, we can use Retrofit to support Observable API calls (this is just an example, we don't have to use it).
The main point is this project will mostly be used by some backend projects. And with them I think that providing some Observable or CompletableFuture APIs is really a need.
I can also help to develop some code. :)
How to get Ads using facebook java SDK
can you help me to get the ads of a campaign using the facebook java API.
and can u also provide a proper documentation for the facebook-java-ads-sdk.
Saved audiences
Hi.
How do I load all the saved audiences? I managed to load custom audiences with account.getCustomAudiences().requestField("name").execute();
but I don't get the saved audiences.
I see that there is an endpoint for loading saved audiences by id: https://developers.facebook.com/docs/marketing-api/reference/saved-audience/
but how do I get the IDs? :)
Best,
M
SDK - support of API versions
Although it seems like it is designed for supporting multiple versions of the API I see few issues:
- Technical - the current APIContext Constructor that accepts a version is protected and only the default which is defined in the config is available (it's 2.5 for now).
- Conceptual - Versions has breaking changes. We have been writing internally an "SDK" (a bit less generic and holds only the API calls we are using) for a long time. The best way to do it is by providing a package name with the version main.java.....sdk.2-5. Once you have a new version you start with copying it and adding a new package ... skd-2.6 and then you update according to the breaking changes.
This way a client of the library is really able to choose which versions to use, you can maintain one master branch supporting few versions in parallel and once a version is deprecated, you delete the package.
Hope this makes sense
@christinelu FYI
Conversion tracking
Hi,
I'm trying to create an ad with all the Tracking settings in place. By all the tracking settings I mean pixel ID and URL parameters.
I tryed with something like this:
final ConversionActionQuery caq = new ConversionActionQuery();
caq.setFieldFbPixel(Arrays.asList("621916377890091"));
//formatter:off
final Ad ad = account.createAd()
.setName("Java SDK Test ad")
.setAdsetId(Long.parseLong(adSet.getId()))
.setCreative(creative)
.setStatus("PAUSED")
.setBidAmount(100L)
.setRedownload(true)
.setTrackingSpecs(Arrays.asList(caq))
.execute();
//formatter:on
but I get the StackOverflow exception
Caused by: java.lang.StackOverflowError: null
at java.lang.Class.isPrimitive(Native Method) ~[na:1.8.0_65]
at com.google.gson.internal.$Gson$Types.checkNotPrimitive($Gson$Types.java:432) ~[gson-2.3.1.jar:na]
at com.google.gson.internal.$Gson$Types.access$000($Gson$Types.java:43) ~[gson-2.3.1.jar:na]
at com.google.gson.internal.$Gson$Types$WildcardTypeImpl.<init>($Gson$Types.java:542) ~[gson-2.3.1.jar:na]
at com.google.gson.internal.$Gson$Types.canonicalize($Gson$Types.java:109) ~[gson-2.3.1.jar:na]
at com.google.gson.internal.$Gson$Types$WildcardTypeImpl.<init>($Gson$Types.java:551) ~[gson-2.3.1.jar:na]
at com.google.gson.internal.$Gson$Types.canonicalize($Gson$Types.java:109) ~[gson-2.3.1.jar:na]
at com.google.gson.internal.$Gson$Types$WildcardTypeImpl.<init>($Gson$Types.java:544) ~[gson-2.3.1.jar:na]
at com.google.gson.internal.$Gson$Types.canonicalize($Gson$Types.java:109) ~[gson-2.3.1.jar:na]
Any tips on how to make it work with the current SDK?
Thanks!
error create Link Ad Preview
Hi,
I'm not sure it's right place to post this question, it seems happening to python SDK as well.
For me I'm using this java-sdk to develop my app. So I just want to post here, in case any one can take a look and advise.
I'm trying to get ad-preview for a link ad based on
https://developers.facebook.com/docs/marketing-api/reference/ad-creative-link-data/
"The preview iframe received doesn't render creative but showing:
Using unsupported field in object_story_spec: The field force_single_link is not supported in the field link_data of object_story_spec."
Can you advise what need to be done for this field: force_single_link?
I've tried different cases: remove this field from object_story_spec, set true or false, but still having same error.
AdCreative creative = new AdCreative();
AdCreativeObjectStorySpec objStorySpec = new AdCreativeObjectStorySpec();
AdCreativeLinkData linkData = new AdCreativeLinkData();
linkData.setFieldLink(obj.getString("link_url"));
//linkData.setFieldForceSingleLink(false);
linkData.setFieldImageHash(obj.getString("image_hash"));
objStorySpec.setFieldLinkData(linkData);
objStorySpec.setFieldPageId(obj.getString("page_id"));
creative.setFieldObjectStorySpec(objStorySpec);
Thanks
Sang
duplicate ads, ad sets or campaigns in sdk
hi
Would like to know is there any way to I duplicate ads, ad sets or campaigns in sdk , similar to Power Editor.
It will be very helpful.
Duplicate AdSets
Is there any way to quickly duplicate the adsets with its ads and ad creative?
Uploading video caption file fails
Uploading of video captions fails due to the way the default request executor determines mime types based on file extension; it uses a fixed mapping that doesn't include ".srt", so the Facebook API endpoint rejects the request.
A more foolproof method would be to fall back to a default mimetype such as "application/octet-stream" when one can't be determined based on file extension. Files.probeContentType could also be utilized to delegate to more sophisticated user supplied file type detectors such as Tika.
BatchRequest size limit
Hello,
Is there any chance that the 50 requests limit per batch could be increased ?
Thank you !
Kind Regards !
Catalin
[Java SDK] Facebook partnerdata API
Hi guys,
This SDK is really handy however its missing one big feature, if we want to upload data to the /act_<AD_ACCOUNT_ID>/partnerdata
endpoint its not supported. Are there plans to add this one in?
https://developers.facebook.com/docs/marketing-api/data-partners-api
Thanks!
How do we access the batch request's responses?
Avoiding "User request limit reached"
I haven't ran a wireshark (too lazy), but I seem to be running into the issue with 200 requests per hour max over an account with only 25 ads.
I have code that looks like this:
APINodeList ads = adAccount.getAds()..[blah blah blah]..execute() (1 call, returns 25 ads)
Then I go through all ads, requesting insights:
for (Ad ad : ads) {
APINodeList adInsights = ad.getInsights().[blah].execute() (should get called 25 times)
methodThatExaminesInsights(each adInsight)
}
Now considering there should be only 26 calls to go to backend, I getthe 200-max error after going through 180 or so insights. Which means that looking at an insight generates a call?
This seems silly as that means there is no way to examine even a single account's insights
Seems like a bug.
Any help would be appreciated.
Proxy Settings in SDK API
Is there any option to setup proxy settings in sdk/api, because most of organization have proxy server for Internet access. Thanks
AdCreativeLinkDataCallToActionValue is not utilized
When creating an AdCreative, passing an instance of AdCreativeLinkDataCallToActionValue to adCreativeLinkDataCallToAction.setFieldValue(..) doesn't have an effect - those CTA parameters are not present in the resulting adCreative.
Instead, we are forced to use the form adCreativeLinkDataCallToAction.setFieldValue(String s), and pass in json in a string - only then do we see the correct CTA parameters on the resulting adCreative.
Ad Accounts Audience Insights Query
https://developers.facebook.com/docs/marketing-api/reference/ad-account/audience_insights_query
Are are there plans to support this API?
Error Handling Documentation
There is no documentation regarding Error Handling.
Suggest you add some.
@christinelu FYI
Method Account.getInsights() fail
Error Message: Object with ID 'act_5620100000000975' does not exist
I think you need remove "act_" in request.
Fetching businesses leads to NPE
Business.java, row 149, inside parseResponse():
JsonObject paging = obj.get("paging").getAsJsonObject().get("cursors").getAsJsonObject();
This causes a null pointer exception in API when trying to fetch all businesses of a user like this:
APINodeList<Business> x = (APINodeList) ((APINodeList) (new APIRequest(context, "", "/me/businesses", "GET", Business.getParser())).execute());
Reason is that the API endpoint in question doesn't return cursors.
URL tags creating error (V2.6)
Hi,
I'm still using v2.6 and I got this error while creating ad with url_tags having more than 1 value:
creative to submit:
{"body":"test desc","image_hash":"c6e035cb89c48000b7e5eb8af0e2b012","link_url":"http://sdinh.net","object_url":"http://sdinh.net","title":"my headline","url_tags":"key=1&key=2"}
error:
{\"message\":\"(#100) Creative spec must be an associative array (optionally json-encoded)
It happened with different type of creative (Domain, Post page ad...).
Can you take a look and advise.
Thanks,
Sang
Publish to maven central
Better than just making jars available for download
Uploading Custom Audience
There is no guide or example for creating & using custom audience. Uploading Custom audience of phone number, email, Mobile advertising ID etc.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.