From cf7a05f80f68b5b1c8bcc0089679dd497cec2506 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Sun, 14 Jun 2015 23:53:32 -0800 Subject: first commit --- .../src/github.com/huandu/facebook/README.md | 347 +++++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 Godeps/_workspace/src/github.com/huandu/facebook/README.md (limited to 'Godeps/_workspace/src/github.com/huandu/facebook/README.md') diff --git a/Godeps/_workspace/src/github.com/huandu/facebook/README.md b/Godeps/_workspace/src/github.com/huandu/facebook/README.md new file mode 100644 index 000000000..a21de8d7c --- /dev/null +++ b/Godeps/_workspace/src/github.com/huandu/facebook/README.md @@ -0,0 +1,347 @@ +# A Facebook Graph API SDK In Golang # + +[![Build Status](https://travis-ci.org/huandu/facebook.png?branch=master)](https://travis-ci.org/huandu/facebook) + +This is a Go package fully supports Facebook Graph API with file upload, batch request, FQL and multi-FQL. It can be used in Google App Engine. + +API documents can be found on [godoc](http://godoc.org/github.com/huandu/facebook). + +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. + +## Get It ## + +Use `go get -u github.com/huandu/facebook` to get or update it. + +## Usage ## + +### Quick start ### + +Here is a sample to read my Facebook username by uid. + +```go +package main + +import ( + "fmt" + fb "github.com/huandu/facebook" +) + +func main() { + res, _ := fb.Get("/538744468", fb.Params{ + "fields": "username", + "access_token": "a-valid-access-token", + }) + fmt.Println("here is my facebook username:", res["username"]) +} +``` + +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. + +```go +// Decode "username" to a Go string. +var username string +res.DecodeField("username", &username) +fmt.Println("alternative way to get username:", username) + +// It's also possible to decode the whole result into a predefined struct. +type User struct { + Username string +} + +var user User +res.Decode(&user) +fmt.Println("print username in struct:", user.Username) +``` + +### Read a graph `user` object with a valid access token ### + +```go +res, err := fb.Get("/me/feed", fb.Params{ + "access_token": "a-valid-access-token", +}) + +if err != nil { + // err can be an facebook API error. + // if so, the Error struct contains error details. + if e, ok := err.(*Error); ok { + fmt.Logf("facebook error. [message:%v] [type:%v] [code:%v] [subcode:%v]", + e.Message, e.Type, e.Code, e.ErrorSubcode) + return + } + + return +} + +// read my last feed. +fmt.Println("my latest feed story is:", res.Get("data.0.story")) +``` + +### Read a graph `search` for page and decode slice of maps + +```go +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.Logf("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 controls over all API calls. They can also make code clear and concise. + +```go +// 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 in late 2013. +globalApp.RedirectUri = "http://your.site/canvas/url/" + +// here comes a client with a facebook signed request string in query string. +// creates a new session with signed request. +session, _ := globalApp.SessionFromSignedRequest(signedRequest) + +// if there is another way to get decoded access token, +// creates a session directly with the token. +session := globalApp.Session(token) + +// validate access token. err is nil if token is valid. +err := session.Validate() + +// use session to send api request with access token. +res, _ := session.Get("/me/feed", nil) +``` + +### 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. + +```go +res, _ := session.Get("/me/home", nil) + +// create a paging structure. +paging, _ := res.Paging(session) + +// get current results. +results := paging.Data() + +// get next page. +noMore, err := paging.Next() +results = paging.Data() +``` + +### Read graph api response and decode result into a struct ### + +As facebook Graph API always uses lower case words as keys in API response. +This package can convert go's camel-case-style struct field name to facebook's underscore-style API key name. + +For instance, to decode following JSON response... + +```json +{ + "foo_bar": "player" +} +``` + +One can use following struct. + +```go +type Data struct { + FooBar string // "FooBar" maps to "foo_bar" in JSON automatically in this case. +} +``` + +Decoding behavior can be changed per field through field tag -- just like what `encoding/json` does. + +Following is a sample shows all possible field tags. + +```go +// 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. +} + +type FacebookFeedFrom struct { + Name, Id string +} + +// 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 ### + +```go +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") +``` + +### Send FQL query ### + +```go +results, _ := fb.FQL("SELECT username FROM page WHERE page_id = 20531316728") +fmt.Println(results[0]["username"]) // print "facebook" + +// most FQL query requires access token. create session to hold access token. +session := &fb.Session{} +session.SetAccessToken("A-VALID-ACCESS-TOKEN") +results, _ := session.FQL("SELECT username FROM page WHERE page_id = 20531316728") +fmt.Println(results[0]["username"]) // print "facebook" +``` + +### Make multi-FQL ### + +```go +res, _ := fb.MultiFQL(Params{ + "query1": "SELECT username FROM page WHERE page_id = 20531316728", + "query2": "SELECT uid FROM user WHERE uid = 538744468", +}) +var query1, query2 []Result + +// get response for query1 and query2. +res.DecodeField("query1", &query1) +res.DecodeField("query2", &query2) + +// most FQL query requires access token. create session to hold access token. +session := &fb.Session{} +session.SetAccessToken("A-VALID-ACCESS-TOKEN") +res, _ := session.MultiFQL(Params{ + "query1": "...", + "query2": "...", +}) + +// same as the sample without access token... +``` + +### Use it in Google App Engine ### + +Google App Engine provide `appengine/urlfetch` package as standard http client package. Default client in `net/http` doesn't work. One must explicitly set http client in `Session` to make it work. + +```go +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](https://developers.facebook.com/docs/apps/versions) to understand facebook versioning strategy. + +```go +// this package uses default version which is controlled by facebook app setting. +// change following global variable to specific a global default version. +fb.Version = "v2.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 = "v2.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](https://developers.facebook.com/docs/graph-api/securing-requests) to know more about it. + +```go +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 introduces a way to debug graph API calls. See [Debugging API Requests](https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#debugging) for details. + +This package provides both 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 result. + +```go +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) +``` + +## Change Log ## + +See [CHANGELOG.md](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 support. Such APIs are deprecated for years. Forget about them. + +## License ## + +This package is licensed under MIT license. See LICENSE for details. -- cgit v1.2.3-1-g7c22