huandu/facebook Go SDK

repository·master·Indexed 23 days ago

https://github.com/huandu/facebook

A Go SDK for the Facebook Graph API supporting file uploads, batch requests, and the Marketing API. It provides tools for managing App and Session configurations, decoding API responses into Go structs using custom tags, handling paginated results, and managing OAuth tokens. The library is compatible with Google App Engine and supports both package-level global functions and instance-based production workflows.

Tokens
6.8K
Snippets
12
Records
49
Agent score
80%

What's inside huandu/facebook

  1. Quick start with Facebook Graph API

    master

    You can perform basic Graph API requests using package-level functions like fb.Get. The result is returned as an fb.Result (which is a map[string]interface{}).

    package main
    
    import (
        "fmt"
        fb "github.com/huandu/facebook/v2"
    )
    
    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"])
    }
    package main
    
    import (
        "fmt"
        fb "github.com/huandu/facebook/v2"
    )
    
    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"])
    }
  2. Install the Facebook Graph API SDK for Go

    master

    To install the SDK, use the following commands depending on whether you are using Go modules:

    With Go modules (recommended):

    go get github.com/huandu/facebook/v2

    Without Go modules:

    go get -u github.com/huandu/facebook

    Important Note on Import Paths: Since Go 1.14, incompatible major versions are omitted from the path unless explicitly specified. It is highly recommended to use the v2 import path (github.com/huandu/facebook/v2) to avoid dependency errors.

  3. Use `App` and `Session` for production

    master

    For production applications, it is recommended to use fb.App and fb.Session instead of package-level functions. App holds your credentials, and Session manages specific access tokens and configurations.

    • fb.New(appID, appSecret): Creates a new App instance.
    • app.Session(token): Creates a session from an access token.
    • app.SessionFromSignedRequest(signedRequest): Creates a session from a Facebook signed request.
    • session.Validate(): Validates the access token.
    • session.BaseURL: Can be overridden for unit testing.
    • session.RFC3339Timestamps: When set to true, requests date_format=Y-m-d\TH:i:sP to ensure compatibility with Go's encoding/json.
  4. Customize struct decoding with `facebook` tags

    master

    The SDK uses the facebook struct tag to map API response keys to Go fields. It also supports the standard json tag. If both are present, the facebook tag takes precedence. You can also use the required flag.

    Supported tags:

    • facebook:"field_name": Maps to a specific key.
    • facebook:",required": Marks the field as required in the response.
    • facebook:"-": Omits the field during decoding.
    type FacebookFeed struct {
        Id          string            `facebook:",required"` 
        Story       string
        FeedFrom    *FacebookFeedFrom `facebook:"from"`                  
        CreatedTime string            `facebook:"created_time,required"` 
        Omitted     string            `facebook:"-"` 
    }
    
    type FacebookFeedFrom struct {
        Name string `json:"name"`                   
        Id string   `facebook:"id" json:"shadowed"` 
    }
  5. Configure API version and `appsecret_proof`

    master

    API Versioning

    You can set a global default version using fb.Version or specify a version per session using session.Version.

    App Secret Proof

    To secure requests, you can enable appsecret_proof. This can be set globally on an App instance or per Session.

    • globalApp.EnableAppsecretProof = true
    • session.EnableAppsecretProof(false)
  6. Implement a custom HttpClient

    master

    The Session allows you to provide your own HTTP client by setting the HttpClient field. This is useful for custom middleware, logging, or specialized transport layers. The client must satisfy the HttpClient interface:

    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)
    }

    Note: This interface is designed to be compatible with *http.Client.

  7. Use special number types for flexible decoding

    master

    The SDK provides several custom types that allow for more flexible JSON decoding. Specifically, these types can be decoded from either a JSON number or a JSON string (e.g., if Facebook returns a large ID as a string to prevent precision loss).

    Available types:

    • Integers: Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64
    • Floats: Float32, Float64

    Using these in your structs with Result.Decode or Result.DecodeField allows the SDK to implicitly parse strings into the appropriate numeric type.

  8. Decode Facebook responses into structs with custom tags

    master

    When using Result.Decode, you can control how fields are mapped from the Facebook JSON response using struct tags. The package recommends using the facebook tag, but the json tag is also supported as a fallback.

    Supported tag features:

    • facebook:"name": Maps the field to the specific key name in the JSON response.
    • facebook:",required": Marks a field as mandatory. Decode will return an error if this field is missing from the response.
    • facebook:"-": Tells the decoder to ignore this field.

    Note: If both facebook and json tags are present, the facebook tag takes precedence.

    type Foo struct {
        // "id" must exist in response.
        Id string `facebook:",required"` 
    
        // Use "name" as the field name in the response.
        TheName string `facebook:"name"` 
    
        // The "json" key also works.
        Key string `json:"my_key"` 
    
        // If both are set, "facebook" is used.
        Value string `facebook:"value" json:"shadowed"` 
    }
  9. Upload binary data using BinaryData and BinaryFile

    master

    To send files or binary content in a request, include *BinaryData or *BinaryFile in your Params. This triggers multipart/form-data encoding.

    • *BinaryData: Use this to upload data from an io.Reader (the Source field). You must provide a Filename and ContentType.
    • *BinaryFile: Use this to upload a file from the local filesystem using a Path. If Path is empty, it defaults to the Filename.

    When using these types, the Encode method will create the appropriate multipart form parts.

  10. Handle Facebook API and Unmarshal errors

    master

    When making requests, errors can be of two main types:

    1. *Error: Represents a Facebook API error (contains Message, Type, Code, ErrorSubcode, and TraceID).
    2. *UnmarshalError: Occurs when the API returns a non-JSON response (contains Message, Err, and the raw Payload).
    res, err := fb.Get("/me/feed", fb.Params{
         "access_token": "a-valid-access-token",
    })
    
    if err != nil {
        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
        }
    
        if e, ok := err.(*UnmarshalError); ok {
            fmt.Printf("facebook error. [message:%v] [err:%v] [payload:%v]",
                e.Message, e.Err, string(e.Payload))
            return
        }
        return
    }
  11. Send batch requests

    master

    Use fb.BatchApi to send multiple requests in a single call. Each request is defined using fb.Params specifying the method (e.g., fb.GET) and the relative_url.

    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 {
        return
    }
    
    // Access individual results
    batchResult1, _ := results[0].Batch()
    res := batchResult1.Result
  12. Decode `fb.Result` into Go types or structs

    master

    The fb.Result type provides methods to safely decode API responses into Go variables or predefined structs. If a type implements json.Unmarshaler (like time.Time), Decode and DecodeField will use it.

    Use DecodeField to extract a specific key, or Decode to map the entire response to a struct. The SDK automatically handles the conversion from Facebook's snake_case to Go's CamelCase struct fields.

    // Decode "first_name" to a Go string.
    var first_name string
    res.DecodeField("first_name", &first_name)
    
    // Decode the whole result into a predefined struct.
    type User struct {
        FirstName string
    }
    
    var user User
    res.Decode(&user)