Sample code for 30+ languages & platforms
Go

Facebook Download all Photos to Local Files

See more Facebook Examples

Demonstrates how to download all of one's Facebook photos to a local filesystem directory. This sample code keeps a local cache to avoid re-downloading the same photos twice. The program can be run again after a time, and it will download only photos that haven't yet been downloaded.

Chilkat Go Downloads

Go
    success := false

    // This example requires the Chilkat API to have been previously unlocked.
    // See Global Unlock Sample for sample code.

    // This example will use a local disk cache to avoid re-fetching the same
    // photo id after it's been fetched once.
    fbCache := chilkat.NewCache()
    // The cache will use 1 level of 256 sub-directories.
    fbCache.SetLevel(1)
    // Use a directory path that makes sense on your operating system..
    fbCache.AddRoot("C:/fbCache")

    // This example assumes a previously obtained an access token
    oauth2 := chilkat.NewOAuth2()
    oauth2.SetAccessToken("FACEBOOK-ACCESS-TOKEN")

    rest := chilkat.NewRest()

    // Connect to Facebook.
    success = rest.Connect("graph.facebook.com",443,true,true)
    if success != true {
        fmt.Println(rest.LastErrorText())
        fbCache.DisposeCache()
        oauth2.DisposeOAuth2()
        rest.DisposeRest()
        return
    }

    // Provide the authentication credentials (i.e. the access key)
    rest.SetAuthOAuth2(oauth2)

    // There are two choices:  
    // We can choose to download the photos the person is tagged in or has uploaded
    // by setting type to "tagged" or "uploaded".
    rest.AddQueryParam("type","uploaded")

    // To download all photos, we begin with an outer loop that iterates over
    // the list of photo nodes in pages.  Each page returned contains a list of 
    // photo node ids.  Each photo node id must be retrieved to get the download URL(s)
    // of the actual image.

    // I don't know the max limit for the number of records that can be downloaded at once.
    rest.AddQueryParam("limit","100")

    // Get the 1st page of photos ids.
    // See https://developers.facebook.com/docs/graph-api/reference/user/photos/ for more information.
    responseJson := rest.FullRequestNoBody("GET","/v2.7/me/photos")
    if rest.LastMethodSuccess() != true {
        fmt.Println(rest.LastErrorText())
        fbCache.DisposeCache()
        oauth2.DisposeOAuth2()
        rest.DisposeRest()
        return
    }

    photoJson := chilkat.NewJsonObject()
    saPhotoUrls := chilkat.NewStringArray()
    sbPhotoIdPath := chilkat.NewStringBuilder()

    json := chilkat.NewJsonObject()
    json.SetEmitCompact(false)
    json.Load(*responseJson)

    var i int
    var photoId *string = new(string)
    var imageUrl *string = new(string)

    // Get the "after" cursor.
    afterCursor := json.StringOf("paging.cursors.after")
    for json.LastMethodSuccess() == true {

        fmt.Println("-------------------")
        fmt.Println("afterCursor = ", *afterCursor)

        // For each photo id in this page...
        i = 0
        numItems := json.SizeOfArray("data")
        for i < numItems {
            json.SetI(i)
            photoId = json.StringOf("data[i].id")
            fmt.Println("photoId = ", *photoId)

            // We need to fetch the JSON for this photo.  Check to see if it's in the local disk cache,
            // and if not, then get it from Facebook.
            photoJsonStr := fbCache.FetchText(*photoId)
            if fbCache.LastMethodSuccess() == false {
                // It's not locally available, so get it from Facebook..
                sbPhotoIdPath.Clear()
                sbPhotoIdPath.Append("/v2.7/")
                sbPhotoIdPath.Append(*photoId)

                rest.ClearAllQueryParams()
                rest.AddQueryParam("fields","id,album,images")

                fmt.Println("Fetching photo node from Facebook...")

                // This REST request will continue using the existing connection.
                // If the connection was closed, it will automatically reconnect to send the request.
                photoJsonStr = rest.FullRequestNoBody("GET",*sbPhotoIdPath.GetAsString())
                if rest.LastMethodSuccess() != true {
                    fmt.Println(rest.LastErrorText())
                    fbCache.DisposeCache()
                    oauth2.DisposeOAuth2()
                    rest.DisposeRest()
                    photoJson.DisposeJsonObject()
                    saPhotoUrls.DisposeStringArray()
                    sbPhotoIdPath.DisposeStringBuilder()
                    json.DisposeJsonObject()
                    return
                }

                // Add the photo JSON to the local cache.
                fbCache.SaveTextNoExpire(*photoId,"",*photoJsonStr)
            }

            // Parse the photo JSON and add the main photo download URL to saPhotoUrls
            // There may be multiple URLs in the images array, but the 1st one is the largest and main photo URL.
            // The others are smaller sizes of the same photo.
            photoJson.Load(*photoJsonStr)
            imageUrl = photoJson.StringOf("images[0].source")
            if photoJson.LastMethodSuccess() == true {

                // Actually, we'll add a small JSON document that contains both the image ID and the URL.
                imgUrlJson := chilkat.NewJsonObject()
                imgUrlJson.AppendString("id",*photoId)
                imgUrlJson.AppendString("url",*imageUrl)
                saPhotoUrls.Append(*imgUrlJson.Emit())
                fmt.Println("imageUrl = ", *imageUrl)
            }

            i = i + 1
        }

        // Prepare for getting the next page of photos ids.
        // We can continue using the same REST object.
        // If already connected, we'll continue using the existing connection.
        // Otherwise, a new connection will automatically be made if needed.
        rest.ClearAllQueryParams()
        rest.AddQueryParam("type","uploaded")
        rest.AddQueryParam("limit","20")
        rest.AddQueryParam("after",*afterCursor)

        // Get the next page of photo ids.
        responseJson = rest.FullRequestNoBody("GET","/v2.7/me/photos")
        if rest.LastMethodSuccess() != true {
            fmt.Println(rest.LastErrorText())
            fbCache.DisposeCache()
            oauth2.DisposeOAuth2()
            rest.DisposeRest()
            photoJson.DisposeJsonObject()
            saPhotoUrls.DisposeStringArray()
            sbPhotoIdPath.DisposeStringBuilder()
            json.DisposeJsonObject()
            imgUrlJson.DisposeJsonObject()
            return
        }

        json.Load(*responseJson)
        afterCursor = json.StringOf("paging.cursors.after")
    }

    fmt.Println("No more pages of photos.")

    // Now iterate over the photo URLs and download each to a file.
    // We can use Chilkat HTTP.  No Facebook authorization (access token) is required to download
    // the photo once the URL is known.  
    http := chilkat.NewHttp()

    // We'll cache the image data so that if run again, we don't re-download the same image again.
    numUrls := saPhotoUrls.Count()
    i = 0
    urlJson := chilkat.NewJsonObject()
    var imageBytes []byte
    fac := chilkat.NewFileAccess()

    for i < numUrls {
        urlJson.Load(*saPhotoUrls.GetString(i))
        photoId = urlJson.StringOf("id")
        imageUrl = urlJson.StringOf("url")

        // Check the local cache for the image data.
        // Only download and save if not already cached.
        imageBytes = fbCache.FetchFromCache(*imageUrl)
        if fbCache.LastMethodSuccess() == false {
            //  This photo needs to be downloaded.

            sbImageUrl := chilkat.NewStringBuilder()
            sbImageUrl.Append(*imageUrl)

            // Let's form a filename..
            extension := ".jpg"
            if sbImageUrl.Contains(".gif",false) == true {
                extension = ".gif"
            }

            if sbImageUrl.Contains(".png",false) == true {
                extension = ".png"
            }

            if sbImageUrl.Contains(".tiff",false) == true {
                extension = ".tiff"
            }

            if sbImageUrl.Contains(".bmp",false) == true {
                extension = ".bmp"
            }

            sbLocalFilePath := chilkat.NewStringBuilder()
            sbLocalFilePath.Append("C:/Photos/facebook/uploaded/")
            sbLocalFilePath.Append(*photoId)
            sbLocalFilePath.Append(extension)

            imageBytes = http.QuickGet(*imageUrl)
            if http.LastMethodSuccess() != true {
                fmt.Println(http.LastErrorText())
                fbCache.DisposeCache()
                oauth2.DisposeOAuth2()
                rest.DisposeRest()
                photoJson.DisposeJsonObject()
                saPhotoUrls.DisposeStringArray()
                sbPhotoIdPath.DisposeStringBuilder()
                json.DisposeJsonObject()
                imgUrlJson.DisposeJsonObject()
                http.DisposeHttp()
                urlJson.DisposeJsonObject()
                fac.DisposeFileAccess()
                sbImageUrl.DisposeStringBuilder()
                sbLocalFilePath.DisposeStringBuilder()
                return
            }

            // We've downloaded the photo image bytes into memory.
            // Save it to the cache AND save it to the output file.
            fbCache.SaveToCacheNoExpire(*imageUrl,"",imageBytes)
            fac.WriteEntireFile(*sbLocalFilePath.GetAsString(),imageBytes)

            fmt.Println("Downloaded to ", *sbLocalFilePath.GetAsString())
        }

        i = i + 1
    }

    fmt.Println("Finished downloading all Facebook photos!")

    fbCache.DisposeCache()
    oauth2.DisposeOAuth2()
    rest.DisposeRest()
    photoJson.DisposeJsonObject()
    saPhotoUrls.DisposeStringArray()
    sbPhotoIdPath.DisposeStringBuilder()
    json.DisposeJsonObject()
    imgUrlJson.DisposeJsonObject()
    http.DisposeHttp()
    urlJson.DisposeJsonObject()
    fac.DisposeFileAccess()
    sbImageUrl.DisposeStringBuilder()
    sbLocalFilePath.DisposeStringBuilder()