diff --git a/README.md b/README.md index d4ccb95..8e102a6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![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. +This is a Go package fully supports Facebook Graph API with file upload, batch request, marketing API. It can be used in Google App Engine. API documents can be found on [godoc](http://godoc.org/github.com/huandu/facebook). @@ -235,47 +235,6 @@ res.DecodeField("id", &id) contentType := batchResult1.Header.Get("Content-Type") ``` -### Send FQL query ### - -*FQL is deprecated by facebook right now.* - -```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 ### - -*FQL is deprecated by facebook right now.* - -```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 provides `appengine/urlfetch` package as the standard http client package. The default client in `net/http` doesn't work. One must explicitly set http client in `Session` to make it work. @@ -392,7 +351,7 @@ 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. +2. No old RESTful API and FQL support. Such APIs are deprecated for years. Forget about them. ## License ## diff --git a/api.go b/api.go index 8e5e48d..778f37a 100644 --- a/api.go +++ b/api.go @@ -136,30 +136,6 @@ func Batch(batchParams Params, params ...Params) ([]Result, error) { return defaultSession.Batch(batchParams, params...) } -// [Deprecated] Makes a FQL query with default session. -// Returns a slice of Result. If there is no query result, the result is nil. -// -// FQL can only make query without "access_token". For query requiring "access_token", create -// Session and call its FQL method. -// -// Facebook document: https://developers.facebook.com/docs/technical-guides/fql#query -func FQL(query string) ([]Result, error) { - return defaultSession.FQL(query) -} - -// [Deprecated] Makes a multi FQL query with default session. -// Returns a parsed Result. The key is the multi query key, and the value is the query result. -// -// MultiFQL can only make query without "access_token". For query requiring "access_token", create -// Session and call its MultiFQL method. -// -// See Session.MultiFQL document for samples. -// -// Facebook document: https://developers.facebook.com/docs/technical-guides/fql#multi -func MultiFQL(queries Params) (Result, error) { - return defaultSession.MultiFQL(queries) -} - // 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) diff --git a/session.go b/session.go index 2fe7893..0160e59 100644 --- a/session.go +++ b/session.go @@ -73,121 +73,6 @@ func (session *Session) Batch(batchParams Params, params ...Params) ([]Result, e return session.graphBatch(batchParams, params...) } -// Makes a FQL query. -// Returns a slice of Result. If there is no query result, the result is nil. -// -// Facebook document: https://developers.facebook.com/docs/technical-guides/fql#query -func (session *Session) FQL(query string) ([]Result, error) { - res, err := session.graphFQL(Params{ - "q": query, - }) - - if err != nil { - return nil, err - } - - // query result is stored in "data" field. - var data []Result - err = res.DecodeField("data", &data) - - if err != nil { - return nil, err - } - - return data, nil -} - -// Makes a multi FQL query. -// Returns a parsed Result. The key is the multi query key, and the value is the query result. -// -// Here is a multi-query sample. -// -// res, _ := session.MultiFQL(Params{ -// "query1": "SELECT name FROM user WHERE uid = me()", -// "query2": "SELECT uid1, uid2 FROM friend WHERE uid1 = me()", -// }) -// -// // Get query results from response. -// var query1, query2 []Result -// res.DecodeField("query1", &query1) -// res.DecodeField("query2", &query2) -// -// Facebook document: https://developers.facebook.com/docs/technical-guides/fql#multi -func (session *Session) MultiFQL(queries Params) (Result, error) { - res, err := session.graphFQL(Params{ - "q": queries, - }) - - if err != nil { - return res, err - } - - // query result is stored in "data" field. - var data []Result - err = res.DecodeField("data", &data) - - if err != nil { - return nil, err - } - - if data == nil { - return nil, fmt.Errorf("multi-fql result is not found.") - } - - // Multi-fql data structure is: - // { - // "data": [ - // { - // "name": "query1", - // "fql_result_set": [ - // {...}, {...}, ... - // ] - // }, - // { - // "name": "query2", - // "fql_result_set": [ - // {...}, {...}, ... - // ] - // }, - // ... - // ] - // } - // - // Parse the structure to following go map. - // { - // "query1": [ - // // Come from field "fql_result_set". - // {...}, {...}, ... - // ], - // "query2": [ - // {...}, {...}, ... - // ], - // ... - // } - var name string - var apiResponse interface{} - var ok bool - result := Result{} - - for k, v := range data { - err = v.DecodeField("name", &name) - - if err != nil { - return nil, fmt.Errorf("missing required field 'name' in multi-query data.%v. %v", k, err) - } - - apiResponse, ok = v["fql_result_set"] - - if !ok { - return nil, fmt.Errorf("missing required field 'fql_result_set' in multi-query data.%v.", k) - } - - result[name] = apiResponse - } - - return result, nil -} - // Makes an arbitrary HTTP request. // It expects server responses a facebook Graph API response. // request, _ := http.NewRequest("https://graph.facebook.com/538744468", "GET", nil) @@ -430,35 +315,6 @@ func (session *Session) graphBatch(batchParams Params, params ...Params) ([]Resu return res, err } -func (session *Session) graphFQL(params Params) (res Result, err error) { - if params == nil { - params = Params{} - } - - session.prepareParams(params) - - // encode url. - buf := &bytes.Buffer{} - buf.WriteString(domainMap["graph"]) - buf.WriteString("fql?") - _, err = params.Encode(buf) - - if err != nil { - return nil, fmt.Errorf("cannot encode params. %v", err) - } - - // it seems facebook disallow POST to /fql. always use GET for FQL. - var response *http.Response - response, err = session.sendGetRequest(buf.String(), &res) - session.addDebugInfo(res, response) - - if res != nil { - err = res.Err() - } - - return -} - func (session *Session) prepareParams(params Params) { if _, ok := params["access_token"]; !ok && session.accessToken != "" { params["access_token"] = session.accessToken diff --git a/session_test.go b/session_test.go index f695e78..1a0df93 100644 --- a/session_test.go +++ b/session_test.go @@ -167,114 +167,6 @@ func TestUploadBinaryWithBatch(t *testing.T) { t.Logf("batch call result. [result:%v]", result) } -// deprecated. -func _TestSimpleFQL(t *testing.T) { - defer func() { - Version = "" - }() - - test := func(t *testing.T, session *Session) { - me, err := session.FQL("SELECT name FROM user WHERE uid = 538744468") - - if err != nil { - t.Fatalf("cannot get my info. [e:%v]", err) - } - - if len(me) != 1 { - t.Fatalf("expect to get only 1 result. [len:%v]", len(me)) - } - - t.Logf("my name. %v", me[0]["name"]) - } - - // v2.2 api doesn't allow me to query user without access token. - if FB_TEST_VALID_ACCESS_TOKEN == "" { - return - } - - Version = "v2.2" - session := &Session{} - session.SetAccessToken(FB_TEST_VALID_ACCESS_TOKEN) - test(t, session) -} - -// deprecated. -func _TestMultiFQL(t *testing.T) { - defer func() { - Version = "" - }() - - test := func(t *testing.T, session *Session) { - res, err := session.MultiFQL(Params{ - "query1": "SELECT username FROM page WHERE page_id = 20531316728", - "query2": "SELECT uid FROM user WHERE uid = 538744468", - }) - - if err != nil { - t.Fatalf("cannot get my info. [e:%v]", err) - } - - if err = res.Err(); err != nil { - t.Fatalf("fail to parse facebook api error. [e:%v]", err) - } - - var query1, query2 []Result - - err = res.DecodeField("query1", &query1) - - if err != nil { - t.Fatalf("cannot get result of query1. [e:%v]", err) - } - - if len(query1) != 1 { - t.Fatalf("expect to get only 1 result in query1. [len:%v]", len(query1)) - } - - err = res.DecodeField("query2", &query2) - - if err != nil { - t.Fatalf("cannot get result of query2. [e:%v]", err) - } - - if len(query2) != 1 { - t.Fatalf("expect to get only 1 result in query2. [len:%v]", len(query2)) - } - - var username string - var uid string - - err = query1[0].DecodeField("username", &username) - - if err != nil { - t.Fatalf("cannot decode username from query1. [e:%v]", err) - } - - if username != "facebook" { - t.Fatalf("username is expected to be 'facebook'. [username:%v]", username) - } - - err = query2[0].DecodeField("uid", &uid) - - if err != nil { - t.Fatalf("cannot decode username from query2. [e:%v] [query2:%v]", err, query2) - } - - if uid != "538744468" { - t.Fatalf("username is expected to be 'facebook'. [username:%v]", username) - } - } - - // v2.2 api doesn't allow me to query user without access token. - if FB_TEST_VALID_ACCESS_TOKEN == "" { - return - } - - Version = "v2.2" - session := &Session{} - session.SetAccessToken(FB_TEST_VALID_ACCESS_TOKEN) - test(t, session) -} - func TestGraphDebuggingAPI(t *testing.T) { if FB_TEST_VALID_ACCESS_TOKEN == "" { t.Skipf("cannot call batch api without access token. skip this test.")