facebook

package module
v2.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 4, 2020 License: MIT Imports: 25 Imported by: 0

README

A Facebook Graph API SDK In Golang

Build Status GoDoc

This is a Go package that fully supports the Facebook Graph API with file upload, batch request and marketing API. It can be used in Google App Engine.

API documentation can be found on godoc.

Feel free to create an issue or send me a pull request if you have any "how-to" question or bug or suggestion when using this package. I'll try my best to reply it.

Install

If go mod is enabled, install this package with go get github.com/huandu/facebook/v2. If not, call go get -u github.com/huandu/facebook to get latest master branch version.

Note that, since go1.14, incompatible versions are omitted unless specified explicitly. Therefore, it's highly recommended to upgrade the import path to github.com/huandu/facebook/v2 when possible to avoid any potential dependency error.

Usage

Quick start

Here is a sample that reads my Facebook first name by uid.

package main

import (
    "fmt"
    fb "github.com/huandu/facebook"
)

func main() {
    res, _ := fb.Get("/538744468", fb.Params{
        "fields": "first_name",
        "access_token": "a-valid-access-token",
    })
    fmt.Println("Here is my Facebook first name:", res["first_name"])
}

The type of res is fb.Result (a.k.a. map[string]interface{}). This type has several useful methods to decode res to any Go type safely.

// Decode "first_name" to a Go string.
var first_name string
res.DecodeField("first_name", &first_name)
fmt.Println("Here's an alternative way to get first_name:", first_name)

// It's also possible to decode the whole result into a predefined struct.
type User struct {
    FirstName string
}

var user User
res.Decode(&user)
fmt.Println("print first_name in struct:", user.FirstName)

If a type implements the json.Unmarshaler interface, Decode or DecodeField will use it to unmarshal JSON.

res := Result{
    "create_time": "2006-01-02T15:16:17Z",
}

// Type `*time.Time` implements `json.Unmarshaler`.
// res.DecodeField will use the interface to unmarshal data.
var tm time.Time
res.DecodeField("create_time", &tm)
Read a graph user object with a valid access token
res, err := fb.Get("/me/feed", fb.Params{
     "access_token": "a-valid-access-token",
})

if err != nil {
    // err can be a Facebook API error.
    // if so, the Error struct contains error details.
    if e, ok := err.(*Error); ok {
        fmt.Printf("facebook error. [message:%v] [type:%v] [code:%v] [subcode:%v] [trace:%v]",
            e.Message, e.Type, e.Code, e.ErrorSubcode, e.TraceID)
        return
    }

    return
}

// read my last feed story.
fmt.Println("My latest feed story is:", res.Get("data.0.story"))
Read a graph search for page and decode slice of maps
res, _ := fb.Get("/search", fb.Params{
        "access_token": "a-valid-access-token",
        "type":         "page",
        "q":            "nightlife,singapore",
    })

var items []fb.Result

err := res.DecodeField("data", &items)

if err != nil {
    fmt.Printf("An error has happened %v", err)
    return
}

for _, item := range items {
    fmt.Println(item["id"])
}
Use App and Session

It's recommended to use App and Session in a production app. They provide more control over all API calls. They can also make code clearer and more concise.

// Create a global App var to hold app id and secret.
var globalApp = fb.New("your-app-id", "your-app-secret")

// Facebook asks for a valid redirect uri when parsing signed request.
// It's a new enforced policy starting as of late 2013.
globalApp.RedirectUri = "http://your.site/canvas/url/"

// Here comes a client with a Facebook signed request string in query string.
// This will return a new session from a signed request.
session, _ := globalApp.SessionFromSignedRequest(signedRequest)

// If there is another way to get decoded access token,
// this will return a session created directly from the token.
session := globalApp.Session(token)

// This validates the access token by ensuring that the current user ID is properly returned. err is nil if token is valid.
err := session.Validate()

// Use the new session to send an API request with access token.
res, _ := session.Get("/me/feed", nil)

By default all requests are sent to Facebook servers. If you wish to override API base URL for unit-testing purposes - just set respective Session field:

testSrv := httptest.NewServer(someMux)
session.BaseURL = testSrv.URL + "/"

Facebook returns most timestamps in a ISO9601 format which can't be natively parsed by Go's encoding/json. Setting RFC3339Timestamps true on the Session or at the global level will cause proper RFC3339 timestamps to be requested from Facebook. RFC3339 is what encoding/json natively expects.

fb.RFC3339Timestamps = true
session.RFC3339Timestamps = true

Setting either of these to true will cause date_format=Y-m-d\TH:i:sP to be sent as a parameter on every request. The format string is a PHP date() representation of RFC3339. More info is available in this issue.

Use paging field in response.

Some Graph API responses use a special JSON structure to provide paging information. Use Result.Paging() to walk through all data in such results.

res, _ := session.Get("/me/home", nil)

// create a paging structure.
paging, _ := res.Paging(session)

var allResults []Result

// append first page of results to slice of Result
allResults = append(allResults, paging.Data()...)

for {
  // get next page.
  noMore, err := paging.Next()
  if err != nil {
    panic(err)
  }
  if noMore {
    // No more results available
    break
  }
  // append current page of results to slice of Result
  allResults = append(allResults, paging.Data()...)
}

Read Graph API response and decode result into a struct

The Facebook Graph API always uses snake case keys in API response. This package can automatically convert from snake case to Go's camel-case-style style struct field names.

For instance, to decode following JSON response...

{
    "foo_bar": "player"
}

One can use following struct.

type Data struct {
    FooBar string  // "FooBar" maps to "foo_bar" in JSON automatically in this case.
}

The decoding of each struct field can be customized by the format string stored under the facebook key or the "json" key in the struct field's tag. The facebook key is recommended as it's specifically designed for this package.

Following is a sample shows all possible field tags.

// define a Facebook feed object.
type FacebookFeed struct {
    Id          string            `facebook:",required"`             // this field must exist in response.
                                                                     // mind the "," before "required".
    Story       string
    FeedFrom    *FacebookFeedFrom `facebook:"from"`                  // use customized field name "from".
    CreatedTime string            `facebook:"created_time,required"` // both customized field name and "required" flag.
    Omitted     string            `facebook:"-"`                     // this field is omitted when decoding.
}

type FacebookFeedFrom struct {
    Name string `json:"name"`                   // the "json" key also works as expected.
    Id string   `facebook:"id" json:"shadowed"` // if both "facebook" and "json" key are set, the "facebook" key is used.
}

// create a feed object direct from Graph API result.
var feed FacebookFeed
res, _ := session.Get("/me/feed", nil)
res.DecodeField("data.0", &feed) // read latest feed
Send a batch request
params1 := Params{
    "method": fb.GET,
    "relative_url": "me",
}
params2 := Params{
    "method": fb.GET,
    "relative_url": uint64(100002828925788),
}
results, err := fb.BatchApi(your_access_token, params1, params2)

if err != nil {
    // check error...
    return
}

// batchResult1 and batchResult2 are response for params1 and params2.
batchResult1, _ := results[0].Batch()
batchResult2, _ := results[1].Batch()

// Use parsed result.
var id string
res := batchResult1.Result
res.DecodeField("id", &id)

// Use response header.
contentType := batchResult1.Header.Get("Content-Type")
Using with Google App Engine

Google App Engine provides the appengine/urlfetch package as the standard HTTP client package. For this reason, the default client in net/http won't work. One must explicitly set the HTTP client in Session to make it work.

import (
    "appengine"
    "appengine/urlfetch"
)

// suppose it's the appengine context initialized somewhere.
var context appengine.Context

// default Session object uses http.DefaultClient which is not allowed to use
// in appengine. one has to create a Session and assign it a special client.
seesion := globalApp.Session("a-access-token")
session.HttpClient = urlfetch.Client(context)

// now, session uses appengine http client now.
res, err := session.Get("/me", nil)
Select Graph API version

See Platform Versioning to understand Facebook versioning strategy.

// this package uses default version which is controlled by Facebook app setting.
// change following global variable to specific a global default version.
fb.Version = "v3.0"

// starting with Graph API v2.0; it's not allowed to get user information without access token.
fb.Api("huan.du", GET, nil)

// it's possible to specify version per session.
session := &fb.Session{}
session.Version = "v3.0" // overwrite global default.
Enable appsecret_proof

Facebook can verify Graph API Calls with appsecret_proof. It's a feature to make Graph API call more secure. See Securing Graph API Requests to know more about it.

globalApp := fb.New("your-app-id", "your-app-secret")

// enable "appsecret_proof" for all sessions created by this app.
globalApp.EnableAppsecretProof = true

// all calls in this session are secured.
session := globalApp.Session("a-valid-access-token")
session.Get("/me", nil)

// it's also possible to enable/disable this feature per session.
session.EnableAppsecretProof(false)
Debugging API Requests

Facebook has introduced a way to debug Graph API calls. See Debugging API Requests for more details.

This package provides both a package level and per session debug flag. Set Debug to a DEBUG_* constant to change debug mode globally; or use Session#SetDebug to change debug mode for one session.

When debug mode is turned on, use Result#DebugInfo to get DebugInfo struct from the result.

fb.Debug = fb.DEBUG_ALL

res, _ := fb.Get("/me", fb.Params{"access_token": "xxx"})
debugInfo := res.DebugInfo()

fmt.Println("http headers:", debugInfo.Header)
fmt.Println("facebook api version:", debugInfo.FacebookApiVersion)
Monitoring API usage info

Call Result#UsageInfo to get a UsageInfo struct containing both app and page level rate limit information from the result. More information about rate limiting can be found here.

res, _ := fb.Get("/me", fb.Params{"access_token": "xxx"})
usageInfo := res.UsageInfo()

fmt.Println("App level rate limit information:", usageInfo.App)
fmt.Println("Page level rate limit information:", usageInfo.Page)
fmt.Println("Ad account rate limiting information:", usageInfo.AdAccount)
fmt.Println("Business use case usage information:", usageInfo.BusinessUseCase)
Work with package golang.org/x/oauth2

The golang.org/x/oauth2 package can handle the Facebook OAuth2 authentication process and access token quite well. This package can work with it by setting Session#HttpClient to OAuth2's client.

import (
    "golang.org/x/oauth2"
    oauth2fb "golang.org/x/oauth2/facebook"
    fb "github.com/huandu/facebook"
)

// Get Facebook access token.
conf := &oauth2.Config{
    ClientID:     "AppId",
    ClientSecret: "AppSecret",
    RedirectURL:  "CallbackURL",
    Scopes:       []string{"email"},
    Endpoint:     oauth2fb.Endpoint,
}
token, err := conf.Exchange(oauth2.NoContext, "code")

// Create a client to manage access token life cycle.
client := conf.Client(oauth2.NoContext, token)

// Use OAuth2 client with session.
session := &fb.Session{
    Version:    "v2.4",
    HttpClient: client,
}

// Use session.
res, _ := session.Get("/me", nil)
Control timeout and cancelation with Context

The Session accept a Context.

// Create a new context.
ctx, cancel := context.WithTimeout(session.Context(), 100 * time.Millisecond)
defer cancel()

// Call an API with ctx.
// The return value of `session.WithContext` is a shadow copy of original session and
// should not be stored. It can be used only once.
result, err := session.WithContext(ctx).Get("/me", nil)

See this Go blog post about context for more details about how to use Context.

Change Log

See CHANGELOG.md.

Out of Scope

  1. No OAuth integration. This package only provides APIs to parse/verify access token and code generated in OAuth 2.0 authentication process.
  2. No old RESTful API and FQL support. Such APIs are deprecated for years. Forget about them.

License

This package is licensed under the MIT license. See LICENSE for details.

Documentation

Overview

Package facebook is a Go library fully supports Facebook Graph API with file upload and batch request. It can be used in Google App Engine.

Library design is highly influenced by facebook official PHP/JS SDK. If you have experience with PHP/JS SDK, you may feel quite familiar with it.

Go to project home page to see samples. Link: https://github.com/huandu/facebook

Index

Constants

View Source
const (
	// ErrCodeUnknown is unknown facebook graph api error code.
	ErrCodeUnknown = -1
)

Variables

View Source
var (
	// Version is the default facebook api version.
	// It can be any valid version string (e.g. "v2.3") or empty.
	//
	// See https://developers.facebook.com/docs/apps/versions for details.
	Version string

	// Debug is the app level debug mode.
	// After setting DebugMode, all newly created session will use the mode
	// to communicate with graph API.
	//
	// See https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#debugging
	Debug DebugMode

	// RFC3339Timestamps will cause all requests to return RFC3339 formatted timestamps.
	// RFC3339 is the timestamp format that the built in UnmarshalJSON expects.
	RFC3339Timestamps bool
)

Functions

func SetHttpClient

func SetHttpClient(client HttpClient)

SetHttpClient updates the http client of default session.

Types

type AdAccountUsage

type AdAccountUsage struct {
	AccIDUtilPCT float64 `json:"acc_id_util_pct"` // Percentage of calls made for this ad account.
}

AdAccountUsage is the rate limiting header for Ads API.

type AdsInsightsThrottle

type AdsInsightsThrottle struct {
	AppIDUtilPCT float64 `json:"app_id_util_pct"` // The percentage of allocated capacity for the associated app_id has consumed.
	AccIDUtilPCT float64 `json:"acc_id_util_pct"` // The percentage of allocated capacity for the associated ad account_id has consumed.
}

AdsInsightsThrottle is the rate limiting header for Ads Insights API.

type App

type App struct {
	// Facebook app id
	AppId string

	// Facebook app secret
	AppSecret string

	// Facebook app redirect URI in the app's configuration.
	RedirectUri string

	// Enable appsecret proof in every API call to facebook.
	// Facebook document: https://developers.facebook.com/docs/graph-api/securing-requests
	EnableAppsecretProof bool
}

App holds facebook application information.

func New

func New(appID, appSecret string) *App

New creates a new App and sets app id and secret.

func (*App) AppAccessToken

func (app *App) AppAccessToken() string

AppAccessToken gets application access token, useful for gathering public information about users and applications.

func (*App) ExchangeToken

func (app *App) ExchangeToken(accessToken string) (token string, expires int, err error)

ExchangeToken exchanges a short-lived access token to a long-lived access token. Return new access token and its expires time.

func (*App) GetCode

func (app *App) GetCode(accessToken string) (code string, err error)

GetCode gets code from a long lived access token. Return the code retrieved from facebook.

func (*App) ParseCode

func (app *App) ParseCode(code string) (token string, err error)

ParseCode redeems code for a valid access token. It's a shorthand call to ParseCodeInfo(code, "").

In facebook PHP SDK, there is a CSRF state to avoid attack. That state is not checked in this library. Caller is responsible to store and check state if possible.

func (*App) ParseCodeInfo

func (app *App) ParseCodeInfo(code, machineID string) (token string, expires int, newMachineID string, err error)

ParseCodeInfo redeems code for access token and returns extra information. The machineId is optional.

See https://developers.facebook.com/docs/facebook-login/access-tokens#extending

func (*App) ParseSignedRequest

func (app *App) ParseSignedRequest(signedRequest string) (res Result, err error)

ParseSignedRequest parses signed request.

func (*App) Session

func (app *App) Session(accessToken string) *Session

Session creates a session based on current App setting.

func (*App) SessionFromSignedRequest

func (app *App) SessionFromSignedRequest(signedRequest string) (session *Session, err error)

SessionFromSignedRequest creates a session from a signed request. If signed request contains a code, it will automatically use this code to exchange a valid access token.

type BatchResult

type BatchResult struct {
	StatusCode int         // HTTP status code.
	Header     http.Header // HTTP response headers.
	Body       string      // Raw HTTP response body string.
	Result     Result      // Facebook api result parsed from body.
}

BatchResult represents facebook batch API call result. See https://developers.facebook.com/docs/graph-api/making-multiple-requests/#multiple_methods.

type BinaryData

type BinaryData struct {
	Filename    string    // filename used in multipart form writer.
	Source      io.Reader // file data source.
	ContentType string    // content type of the data.
}

BinaryData represents binary data from a given source.

func Data

func Data(filename string, source io.Reader) *BinaryData

Data creates new binary data holder.

func DataWithContentType

func DataWithContentType(filename string, source io.Reader, contentType string) *BinaryData

DataWithContentType creates new binary data holder with arbitrary content type.

type BinaryFile

type BinaryFile struct {
	Filename    string // filename used in multipart form writer.
	Path        string // path to file. must be readable.
	ContentType string // content type of the file.
}

BinaryFile represents a file on disk.

func File

func File(filename string) *BinaryFile

File creates a binary file holder.

func FileAlias

func FileAlias(filename, path string) *BinaryFile

FileAlias creates a binary file holder and specific a different path for reading.

func FileAliasWithContentType

func FileAliasWithContentType(filename, path, contentType string) *BinaryFile

FileAliasWithContentType creates a new binary file holder with arbitrary content type.

type BusinessUseCaseUsage

type BusinessUseCaseUsage map[string][]*RateLimiting

BusinessUseCaseUsage is the business use case usage data.

type DebugInfo

type DebugInfo struct {
	Messages []DebugMessage // debug messages. it can be nil if there is no message.
	Header   http.Header    // all HTTP headers for this response.
	Proto    string         // HTTP protocol name for this response.

	// Facebook debug HTTP headers.
	FacebookApiVersion string // the actual graph API version provided by facebook-api-version HTTP header.
	FacebookDebug      string // the X-FB-Debug HTTP header.
	FacebookRev        string // the x-fb-rev HTTP header.
}

DebugInfo is the debug information returned by facebook when debug mode is enabled.

type DebugMessage

type DebugMessage struct {
	Type    string
	Message string
	Link    string
}

DebugMessage is one debug message in "__debug__" of graph API response.

type DebugMode

type DebugMode string

DebugMode is the debug mode of Graph API. See https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#graphapidebugmode

const (
	DEBUG_OFF DebugMode = "" // turn off debug.

	DEBUG_ALL     DebugMode = "all"
	DEBUG_INFO    DebugMode = "info"
	DEBUG_WARNING DebugMode = "warning"
)

Graph API debug mode values.

type Error

type Error struct {
	Message      string
	Type         string
	Code         int
	ErrorSubcode int    // subcode for authentication related errors.
	UserTitle    string `json:"error_user_title,omitempty"`
	UserMessage  string `json:"error_user_msg,omitempty"`
	IsTransient  bool   `json:"is_transient,omitempty"`
	TraceID      string `json:"fbtrace_id,omitempty"`
}

Error represents Facebook API error.

func (*Error) Error

func (e *Error) Error() string

Error returns error string.

type Float32

type Float32 float32

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Float64

type Float64 float64

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type HttpClient

type HttpClient interface {
	Do(req *http.Request) (resp *http.Response, err error)
	Get(url string) (resp *http.Response, err error)
	Post(url string, bodyType string, body io.Reader) (resp *http.Response, err error)
}

HttpClient is an interface to send http request. This interface is designed to be compatible with type `*http.Client`.

func DefaultHttpClient

func DefaultHttpClient() HttpClient

DefaultHttpClient returns the http client for default session.

type Int

type Int int

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Int16

type Int16 int16

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Int32

type Int32 int32

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Int64

type Int64 int64

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Int8

type Int8 int8

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Method

type Method string

Method is HTTP method for an API call. Can be GET, POST or DELETE.

const (
	GET    Method = "GET"
	POST   Method = "POST"
	DELETE Method = "DELETE"
	PUT    Method = "PUT"
)

Facebook graph api methods.

type PagingResult

type PagingResult struct {
	// contains filtered or unexported fields
}

PagingResult represents facebook API call result with paging information.

func (*PagingResult) Data

func (pr *PagingResult) Data() []Result

Data gets current data.

func (*PagingResult) Decode

func (pr *PagingResult) Decode(v interface{}) (err error)

Decode decodes the current full result to a struct. See Result#Decode.

func (*PagingResult) HasNext

func (pr *PagingResult) HasNext() bool

HasNext checks whether there is next page.

func (*PagingResult) HasPrevious

func (pr *PagingResult) HasPrevious() bool

HasPrevious checks whether there is previous page.

func (*PagingResult) Next

func (pr *PagingResult) Next() (noMore bool, err error)

Next reads next page.

func (*PagingResult) Previous

func (pr *PagingResult) Previous() (noMore bool, err error)

Previous reads previous page.

func (*PagingResult) UsageInfo

func (pr *PagingResult) UsageInfo() *UsageInfo

UsageInfo returns API usage information, including business use case, app, page, ad account rate limiting.

type Params

type Params map[string]interface{}

Params is the params used to send Facebook API request.

For general uses, just use Params as an ordinary map.

For advanced uses, use MakeParams to create Params from any struct.

func MakeParams

func MakeParams(data interface{}) (params Params)

MakeParams makes a new Params instance by given data. Data must be a struct or a map with string keys. MakeParams will change all struct field name to lower case name with underscore. e.g. "FooBar" will be changed to "foo_bar".

Returns nil if data cannot be used to make a Params instance.

func (Params) Encode

func (params Params) Encode(writer io.Writer) (mime string, err error)

Encode encodes params to query string. If map value is not a string, Encode uses json.Marshal() to convert value to string.

Encode may panic if Params contains values that cannot be marshalled to json string.

type RateLimiting

type RateLimiting struct {
	CallCount                   int    `json:"call_count"`                      // Percentage of calls made for this business ad account.
	TotalTime                   int    `json:"total_time"`                      // Percentage of the total CPU time that has been used.
	TotalCPUTime                int    `json:"total_cputime"`                   // Percentage of the total time that has been used.
	Type                        string `json:"type"`                            // Type of rate limit logic being applied.
	EstimatedTimeToRegainAccess int    `json:"estimated_time_to_regain_access"` // Time in minutes to resume calls.
}

RateLimiting is the rate limiting header for business use cases.

type Result

type Result map[string]interface{}

Result is Facebook API call result.

func Api

func Api(path string, method Method, params Params) (Result, error)

Api makes a facebook graph api call with default session.

Method can be GET, POST, DELETE or PUT.

Params represents query strings in this call. Keys and values in params will be encoded into the URL automatically, so there is no need to encode keys or values in params manually. Params can be nil.

If you want to get

https://graph.facebook.com/huandu?fields=name,username

Api should be called as following

Api("/huandu", GET, Params{"fields": "name,username"})

or in a simplified way

Get("/huandu", Params{"fields": "name,username"})

Api is a wrapper of Session.Api(). It's designed for graph api that doesn't require app id, app secret and access token. It can be called in multiple goroutines.

If app id, app secret or access token is required in graph api, caller should create a new facebook session through App instance instead.

func Batch

func Batch(batchParams Params, params ...Params) ([]Result, error)

Batch makes a batch facebook graph api call with default session. Batch is designed for more advanced usage including uploading binary files.

An uploading files sample

// equivalent to following curl command (borrowed from facebook docs)
//     curl \
//         -F 'access_token=…' \
//         -F 'batch=[{"method":"POST","relative_url":"me/photos","body":"message=My cat photo","attached_files":"file1"},{"method":"POST","relative_url":"me/photos","body":"message=My dog photo","attached_files":"file2"}]' \
//         -F 'file1=@cat.gif' \
//         -F 'file2=@dog.jpg' \
//         https://graph.facebook.com
Batch(Params{
    "access_token": "the-access-token",
    "file1": File("cat.gif"),
    "file2": File("dog.jpg"),
}, Params{
    "method": "POST",
    "relative_url": "me/photos",
    "body": "message=My cat photo",
    "attached_files": "file1",
}, Params{
    "method": "POST",
    "relative_url": "me/photos",
    "body": "message=My dog photo",
    "attached_files": "file2",
})

Facebook document: https://developers.facebook.com/docs/graph-api/making-multiple-requests

func BatchApi

func BatchApi(accessToken string, params ...Params) ([]Result, error)

BatchApi makes a batch facebook graph api call with default session.

BatchApi supports most kinds of batch calls defines in facebook batch api document, except uploading binary data. Use Batch to do so.

Note: API response is stored in "body" field of a Result.

results, _ := BatchApi(accessToken, Params{...}, Params{...})

// Use first batch api response.
var res1 *BatchResult
var err error
res1, err = results[0].Batch()

if err != nil {
    // this is not a valid batch api response.
}

// Use BatchResult#Result to get response body content as Result.
res := res1.Result

Facebook document: https://developers.facebook.com/docs/graph-api/making-multiple-requests

func Delete

func Delete(path string, params Params) (Result, error)

Delete is a short hand of Api(path, DELETE, params).

func Get

func Get(path string, params Params) (Result, error)

Get is a short hand of Api(path, GET, params).

func MakeResult

func MakeResult(jsonBytes []byte) (Result, error)

MakeResult makes a Result from facebook Graph API response.

func Post

func Post(path string, params Params) (Result, error)

Post is a short hand of Api(path, POST, params).

func Put

func Put(path string, params Params) (Result, error)

Put is a short hand of Api(path, PUT, params).

func Request

func Request(request *http.Request) (Result, error)

Request makes an arbitrary HTTP request with default session. It expects server responses a facebook Graph API response.

request, _ := http.NewRequest("https://graph.facebook.com/538744468", "GET", nil)
res, err := Request(request)
fmt.Println(res["gender"])  // get "male"

func (Result) Batch

func (res Result) Batch() (*BatchResult, error)

Batch creates a BatchResult for this result and returns error if the Result is not a batch api response.

See BatchApi document for a sample usage.

func (Result) DebugInfo

func (res Result) DebugInfo() *DebugInfo

DebugInfo creates a DebugInfo for this result if this result has "__debug__" key.

func (Result) Decode

func (res Result) Decode(v interface{}) (err error)

Decode decodes full result to a struct. It only decodes fields defined in the struct.

As all facebook response fields are lower case strings, Decode will convert all camel-case field names to lower case string. e.g. field name "FooBar" will be converted to "foo_bar". The side effect is that if a struct has 2 fields with only capital differences, decoder will map these fields to a same result value.

If a field is missing in the result, Decode keeps it unchanged by default.

The decoding of each struct field can be customized by the format string stored under the "facebook" key or the "json" key in the struct field's tag. The "facebook" key is recommended as it's specifically designed for this package.

Examples:

type Foo struct {
    // "id" must exist in response. note the leading comma.
    Id string `facebook:",required"`

    // use "name" as field name in response.
    TheName string `facebook:"name"`

    // the "json" key also works as expected.
    Key string `json:"my_key"`

    // if both "facebook" and "json" key are set, the "facebook" key is used.
    Value string `facebook:"value" json:"shadowed"`
}

To change default behavior, set a struct tag `facebook:",required"` to fields should not be missing.

Returns error if v is not a struct or any required v field name absents in res.

func (Result) DecodeField

func (res Result) DecodeField(field string, v interface{}) error

DecodeField decodes a field of result to any type, including struct. Field name format is defined in Result.Get().

More details about decoding struct see Result.Decode().

func (Result) Err

func (res Result) Err() error

Err returns an error if Result is a Graph API error.

The returned error can be converted to Error by type assertion.

err := res.Err()
if err != nil {
    if e, ok := err.(*Error); ok {
        // read more details in e.Message, e.Code and e.Type
    }
}

For more information about Graph API Errors, see https://developers.facebook.com/docs/reference/api/errors/

func (Result) Get

func (res Result) Get(field string) interface{}

Get gets a field from Result.

Field can be a dot separated string. If field name is "a.b.c", it will try to return value of res["a"]["b"]["c"].

To access array items, use index value in field. For instance, field "a.0.c" means to read res["a"][0]["c"].

It doesn't work with Result which has a key contains dot. Use GetField in this case.

Returns nil if field doesn't exist.

func (Result) GetField

func (res Result) GetField(fields ...string) interface{}

GetField gets a field from Result.

Arguments are treated as keys to access value in Result. If arguments are "a","b","c", it will try to return value of res["a"]["b"]["c"].

To access array items, use index value as a string. For instance, args of "a", "0", "c" means to read res["a"][0]["c"].

Returns nil if field doesn't exist.

func (Result) Paging

func (res Result) Paging(session *Session) (*PagingResult, error)

Paging creates a PagingResult for this Result and returns error if the Result cannot be used for paging.

Facebook uses following JSON structure to response paging information. If "data" doesn't present in Result, Paging will return error.

{
    "data": [...],
    "paging": {
        "previous": "https://graph.facebook.com/...",
        "next": "https://graph.facebook.com/..."
    }
}

func (Result) UsageInfo

func (res Result) UsageInfo() *UsageInfo

UsageInfo returns API usage information, including business use case, app, page, ad account rate limiting.

type Session

type Session struct {
	HttpClient        HttpClient
	Version           string // facebook versioning.
	RFC3339Timestamps bool   // set to true to send date_format=Y-m-d\TH:i:sP on every request which will cause RFC3339 style timestamps to be returned
	BaseURL           string // set to override API base URL - trailing slash is required, e.g. http://127.0.0.1:53453/
	// contains filtered or unexported fields
}

Session holds a facebook session with an access token. Session should be created by App.Session or App.SessionFromSignedRequest.

func (*Session) AccessToken

func (session *Session) AccessToken() string

AccessToken gets current access token.

func (*Session) Api

func (session *Session) Api(path string, method Method, params Params) (Result, error)

Api makes a facebook graph api call.

If session access token is set, "access_token" in params will be set to the token value.

Returns facebook graph api call result. If facebook returns error in response, returns error details in res and set err.

func (*Session) App

func (session *Session) App() *App

App gets associated App.

func (*Session) AppsecretProof

func (session *Session) AppsecretProof() string

AppsecretProof checks appsecret proof is enabled or not.

func (*Session) Batch

func (session *Session) Batch(batchParams Params, params ...Params) ([]Result, error)

Batch makes a batch facebook graph api call. Batch is designed for more advanced usage including uploading binary files.

If session access token is set, "access_token" in batchParams will be set to the token value.

Facebook document: https://developers.facebook.com/docs/graph-api/making-multiple-requests

func (*Session) BatchApi

func (session *Session) BatchApi(params ...Params) ([]Result, error)

BatchApi makes a batch call. Each params represent a single facebook graph api call.

BatchApi supports most kinds of batch calls defines in facebook batch api document, except uploading binary data. Use Batch to upload binary data.

If session access token is set, the token will be used in batch api call.

Returns an array of batch call result on success.

Facebook document: https://developers.facebook.com/docs/graph-api/making-multiple-requests

func (*Session) Context

func (session *Session) Context() context.Context

Context returns the session's context. To change the context, use `Session#WithContext`.

The returned context is always non-nil; it defaults to the background context. For outgoing Facebook API requests, the context controls timeout/deadline and cancelation.

func (*Session) Debug

func (session *Session) Debug() DebugMode

Debug returns current debug mode.

func (*Session) Delete

func (session *Session) Delete(path string, params Params) (Result, error)

Delete is a short hand of Api(path, DELETE, params).

func (*Session) EnableAppsecretProof

func (session *Session) EnableAppsecretProof(enabled bool) error

EnableAppsecretProof enables or disable appsecret proof status. Returns error if there is no App associated with this Session.

func (*Session) Get

func (session *Session) Get(path string, params Params) (Result, error)

Get is a short hand of Api(path, GET, params).

func (*Session) Inspect

func (session *Session) Inspect() (result Result, err error)

Inspect Session access token. Returns JSON array containing data about the inspected token. See https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/#checktoken

func (*Session) Post

func (session *Session) Post(path string, params Params) (Result, error)

Post is a short hand of Api(path, POST, params).

func (*Session) Put

func (session *Session) Put(path string, params Params) (Result, error)

Put is a short hand of Api(path, PUT, params).

func (*Session) Request

func (session *Session) Request(request *http.Request) (res Result, err error)

Request makes an arbitrary HTTP request. It expects server responses a facebook Graph API response.

request, _ := http.NewRequest("https://graph.facebook.com/538744468", "GET", nil)
res, err := session.Request(request)
fmt.Println(res["gender"])  // get "male"

func (*Session) SetAccessToken

func (session *Session) SetAccessToken(token string)

SetAccessToken sets a new access token.

func (*Session) SetDebug

func (session *Session) SetDebug(debug DebugMode) DebugMode

SetDebug updates per session debug mode and returns old mode. If per session debug mode is DEBUG_OFF, session will use global Debug mode.

func (*Session) User

func (session *Session) User() (id string, err error)

User gets current user id from access token.

Returns error if access token is not set or invalid.

It's a standard way to validate a facebook access token.

func (*Session) Validate

func (session *Session) Validate() (err error)

Validate validates Session access token. Returns nil if access token is valid.

func (*Session) WithContext

func (session *Session) WithContext(ctx context.Context) *Session

WithContext returns a shallow copy of session with its context changed to ctx. The provided ctx must be non-nil.

type Uint

type Uint uint

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Uint16

type Uint16 uint16

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Uint32

type Uint32 uint32

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Uint64

type Uint64 uint64

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type Uint8

type Uint8 uint8

Special number types which can be decoded from either a number or a string. If developers intend to use a string in JSON as a number, these types can parse string to a number implicitly in `Result#Decode` or `Result#DecodeField`.

Caveats: Parsing a string to a number may lose accuracy or shadow some errors.

type UsageInfo

type UsageInfo struct {
	App             RateLimiting         `json:"app"`               // HTTP header X-App-Usage.
	Page            RateLimiting         `json:"page"`              // HTTP header X-Page-Usage.
	AdAccount       RateLimiting         `json:"ad_account"`        // HTTP header X-Ad-Account-Usage.
	AdsInsights     AdsInsightsThrottle  `json:"ads_insights"`      // HTTP header x-fb-ads-insights-throttle
	BusinessUseCase BusinessUseCaseUsage `json:"business_use_case"` // HTTP header x-business-use-case-usage.
}

UsageInfo is the app usage (rate limit) information returned by facebook when rate limits are possible.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL