Categorygithub.com/muhfaris/facebook-sdk-go
repositorypackage
0.0.2
Repository: https://github.com/muhfaris/facebook-sdk-go.git
Documentation: pkg.go.dev

# README

Go Report Card

Facebook SDK Go

The Facebook SDK Go is a library with powerful feature that enable Go developer to easily integrate Facebook login and make requests to the Graph API.

Feature

  • Authentication
  • Graph API
  • Marketing API
  • Batch Request

Installation

Special for Login Authentication

Usage


Overview

The Graph API is named after the idea of a "social graph" — a representation of the information on Facebook. It's composed of:

  • nodes — basically individual objects, such as a User, a Photo, a Page, or a Comment
  • edges — connections between a collection of objects and a single object, such as Photos on a Page or Comments on a Photo

Nodes

Reading operations almost always begin with a node. A node is an individual object with a unique ID. For example, there are many User node objects, each with a unique ID representing a person on Facebook. To read a node, you query a specific object's ID. So, to read your User node you would query its ID:

curl -i -X GET "https://graph.facebook.com/{your-user-id}?fields=id,name&access_token={your-user-access-token}"

This request would return the following fields (node properties) by default, formatted using JSON:

{
  "name": "Your Name",
  "id": "your-user-id"
}

Edges

Nodes have edges, which usually can return collections of other nodes which are attached to them. To read an edge, you must include both the node ID and the edge name in the path. For example, /user nodes have a /feed edge which can return all Post nodes on a User. You'll need to get a new access token and select user_posts permissions during the Get access token flow. Here's how you could use the edge to get all your Posts:

curl -i -X GET "https://graph.facebook.com/{your-user-id}/feed?access_token={your-user-access-token}"

The JSON response would look something like this:

{
  "data": [
    {
      "created_time": "2017-12-08T01:08:57+0000",
      "message": "Love this puzzle. One of my favorite puzzles",
      "id": "post-id"
    },
    {
      "created_time": "2017-12-07T20:06:14+0000",
      "message": "You need to add grape as a flavor.",
      "id": "post-id"
    }
  ]
}

Both (Nodes and Edge)

Facebook SDK declaration Nodes and Edges with value 0 and 1:

  • 0 for Nodes
  • 1 for Edges

Default value of SDK is Nodes (0), If you want to request Edges change Graph to 1. the SDK config like below:

package main

import (
	"net/http"

	"github.com/labstack/echo/v4"

	sdk "github.com/muhfaris/facebook-sdk-go"
)

func insights(c echo.Context) error {
	config := sdk.Facebook{
		Token:   "",
		AppKey:  "",
		Version: "v9.0",
		Graph: 1,
	}

	fbSDK, err := sdk.NewFacebook(config)
	if err != nil {
		return c.JSON(http.StatusBadRequest, err)
	}

	resp := fbSDK.Get("<campaign_id>/insights", sdk.WithParamQuery(sdk.ParamQuery{"fields": "reach"}))
	if resp.Error != nil {
		return c.JSON(http.StatusBadRequest, resp)
	}

	return c.JSON(http.StatusOK, resp)
}

func main(){
 	e := echo.New()

	// Routes
	e.GET("/insights", insights)
	e.Logger.Fatal(e.Start(":8989"))
}


APP Secret Proof

When you enable the appsecret_proof in Your app's settings, AppKey is must fill. You can not empty this field.

Login Authentication

Create two API, first use for request to facebook and second for retrive data from facebook.

package main

import (
	"net/http"

	sdk "github.com/muhfaris/facebook-sdk-go"

	"github.com/labstack/echo/v4"
)

var fbSDK sdk.FacebookAPI

// Handler
func login(c echo.Context) error {
	config := sdk.Facebook{
		AppID:       "",
		AppKey:      "",
		Version:     "v9",
		RedirectURL: "https://localhost:8989/callback",
	}

	fbSDK, _ = sdk.NewFacebook(config)

	authenticate := fbSDK.Authenticate("example-state")
	url := authenticate.URL()

	c.Redirect(http.StatusFound, url)
	return nil
}

func callback(c echo.Context) error {
	state := c.FormValue("state")
	authenticate := fbSDK.Authenticate(state)

	code := c.FormValue("code")
	token, _ := authenticate.GetAccessToken(code)

	return c.JSON(http.StatusOK, token)
}

func main() {
	e := echo.New()

	// Routes
	e.GET("/login", login)
	e.GET("/callback", callback)

	// Start server
	// generate ssl certificate use mkcert (https://github.com/FiloSottile/mkcert)
	e.Logger.Fatal(e.StartTLS(":8989", "localhost+2.pem", "localhost+2-key.pem"))
}

Note: Please, generate tls certificate your self.

GET Operation

This example request list ad account from /me/adaccounts.

package main

import (
	"net/http"

	"github.com/labstack/echo/v4"

	sdk "github.com/muhfaris/facebook-sdk-go"
)

func adaccount(c echo.Context) error {
	config := sdk.Facebook{
		Token:   "",
		AppKey:  "",
		Version: "v9.0",
	}

	fbSDK, err := sdk.NewFacebook(config)
	if err != nil {
		return c.JSON(http.StatusBadRequest, err)
	}

	resp := fbSDK.Get("/me/adaccounts")
	if resp.Error != nil {
		return c.JSON(http.StatusBadRequest, resp)
	}

	return c.JSON(http.StatusOK, resp)
}

func main() {
	e := echo.New()

	// Routes
	e.GET("/adaccounts", adaccount)

	// Start server
	// generate ssl certificate use mkcert (https://github.com/FiloSottile/mkcert)
	e.Logger.Fatal(e.Start(":8989"))
}

if you want to request with some fields, just add param query in request:

resp := fbSDK.Get("/me/adaccounts", WithParamQuery(ParamQuery{
	"fields": "name,account_status",
}))

Post Operation

Post operation can use WithBody() for pass of data.

package main

import (
	"net/http"

	"github.com/labstack/echo/v4"

	sdk "github.com/muhfaris/facebook-sdk-go"
)

func campaign(c echo.Context) error {
	config := sdk.Facebook{
		Token:   "",
		AppKey:  "",
		Version: "v9.0",
	}

	fbSDK, err := sdk.NewFacebook(config)
	if err != nil {
		return c.JSON(http.StatusBadRequest, err)
	}

	data := map[string]interface{}{
    	"name":                  "test-1",
    	"special_ad_categories": []string{"NONE"},
    	"objective":             "CONVERSIONS",
    	"status":                "PAUSED",
    	}

	resp := fbSDK.Post("<act_id>/campaigns", WithBody(data))
	if resp.Error != nil {
		return c.JSON(http.StatusBadRequest, resp)
	}

	return c.JSON(http.StatusOK, resp)
}

func main() {
	e := echo.New()

	// Routes
	e.GET("/campaigns", campaign)

	// Start server
	// generate ssl certificate use mkcert (https://github.com/FiloSottile/mkcert)
	e.Logger.Fatal(e.Start(":8989"))
}

Delete Operation

package main

import (
	"net/http"

	"github.com/labstack/echo/v4"

	sdk "github.com/muhfaris/facebook-sdk-go"
)

func campaigns(c echo.Context) error {
	config := sdk.Facebook{
		Token:   "",
		AppKey:  "",
		Version: "v9.0",
	}

	fbSDK, err := sdk.NewFacebook(config)
	if err != nil {
		return c.JSON(http.StatusBadRequest, err)
	}

	resp := fbSDK.Delete(<object_id>)
	if resp.Error != nil {
		return c.JSON(http.StatusBadRequest, resp)
	}

	return c.JSON(http.StatusOK, resp)
}

func main() {
	e := echo.New()

	// Routes
	e.DELETE("/campaigns", campaigns)

	// Start server
	// generate ssl certificate use mkcert (https://github.com/FiloSottile/mkcert)
	e.Logger.Fatal(e.Start(":8989"))
}

Batch Request

package main

import (
	"net/http"

	"github.com/labstack/echo/v4"

	sdk "github.com/muhfaris/facebook-sdk-go"
)

func batch(c echo.Context) error {
	config := sdk.Facebook{
		Token:   "",
		AppKey:  "",
		Version: "v9.0",
	}

	fbSDK, err := sdk.NewFacebook(config)
	if err != nil {
		return c.JSON(http.StatusBadRequest, err)
	}

	batch := ArrayOfBatchBodyRequest{
    	{
    		Method:      "GET",
    		RelativeURL: "/me/adaccountssx",
    	},
    	{
    		Method:      "GET",
    		RelativeURL: "<act_id>/campaigns",
    	},
    }

	resp := fbSDK.Batch(batch)
	if resp.Error != nil {
		return c.JSON(http.StatusBadRequest, resp)
	}

	if _, ok := resp.Data.HasErrors(); ok {
	    // Todo Error
    }

	return c.JSON(http.StatusOK, resp)
}

func main() {
	e := echo.New()

	// Routes
	e.DELETE("/batch", batch)

	// Start server
	// generate ssl certificate use mkcert (https://github.com/FiloSottile/mkcert)
	e.Logger.Fatal(e.Start(":8989"))
}

Contributing

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 to it.

License

This package is licensed under the MIT license.