Sample code for 30+ languages & platforms
Rust

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 Rust Downloads

Rust

// 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.
let fb_cache = chilkat::Cache::new();
// The cache will use 1 level of 256 sub-directories.
fb_cache.set_level(1);
// Use a directory path that makes sense on your operating system..
fb_cache.add_root("C:/fbCache");

// This example assumes a previously obtained an access token
let oauth2 = chilkat::OAuth2::new();
oauth2.set_access_token("FACEBOOK-ACCESS-TOKEN");

let rest = chilkat::Rest::new();

// Connect to Facebook.
if rest.connect("graph.facebook.com", 443, true, true).is_err() {
    println!("{}", rest.last_error_text());
    return;
}

// Provide the authentication credentials (i.e. the access key)
let _ = rest.set_auth_o_auth2(&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".
let _ = rest.add_query_param("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.
let _ = rest.add_query_param("limit", "100");

// Get the 1st page of photos ids.
// See https://developers.facebook.com/docs/graph-api/reference/user/photos/ for more information.
let Ok(mut response_json) = rest.full_request_no_body("GET", "/v2.7/me/photos") else {
    println!("{}", rest.last_error_text());
    return;
};

let photo_json = chilkat::JsonObject::new();
let sa_photo_urls = chilkat::StringArray::new();
let sb_photo_id_path = chilkat::StringBuilder::new();

let json = chilkat::JsonObject::new();
json.set_emit_compact(false);
let _ = json.load(&response_json);

let mut i: i32 = 0;
let mut photo_id = String::new();
let mut image_url = String::new();

// Get the "after" cursor.
let mut after_cursor = json.string_of("paging.cursors.after").unwrap_or_default();
while json.last_method_success() {

    println!("-------------------");
    println!("afterCursor = {}", after_cursor);

    // For each photo id in this page...
    i = 0;
    let num_items = json.size_of_array("data");
    while i < num_items {
        json.set_i(i);
        photo_id = json.string_of("data[i].id").unwrap_or_default();
        println!("photoId = {}", photo_id);

        // 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.
        let mut photo_json_str = fb_cache.fetch_text(&photo_id).unwrap_or_default();
        if !fb_cache.last_method_success() {
            // It's not locally available, so get it from Facebook..
            sb_photo_id_path.clear();
            let _ = sb_photo_id_path.append("/v2.7/");
            let _ = sb_photo_id_path.append(&photo_id);

            let _ = rest.clear_all_query_params();
            let _ = rest.add_query_param("fields", "id,album,images");

            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.
            photo_json_str = rest.full_request_no_body("GET", &sb_photo_id_path.get_as_string().unwrap_or_default()).unwrap_or_default();
            if !rest.last_method_success() {
                println!("{}", rest.last_error_text());
                return;
            }

            // Add the photo JSON to the local cache.
            let _ = fb_cache.save_text_no_expire(&photo_id, "", &photo_json_str);
        }

        // 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.
        let _ = photo_json.load(&photo_json_str);
        image_url = photo_json.string_of("images[0].source").unwrap_or_default();
        if photo_json.last_method_success() {

            // Actually, we'll add a small JSON document that contains both the image ID and the URL.
            let img_url_json = chilkat::JsonObject::new();
            let _ = img_url_json.append_string("id", &photo_id);
            let _ = img_url_json.append_string("url", &image_url);
            let _ = sa_photo_urls.append(&img_url_json.emit().unwrap_or_default());
            println!("imageUrl = {}", image_url);
        }

        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.
    let _ = rest.clear_all_query_params();
    let _ = rest.add_query_param("type", "uploaded");
    let _ = rest.add_query_param("limit", "20");
    let _ = rest.add_query_param("after", &after_cursor);

    // Get the next page of photo ids.
    response_json = rest.full_request_no_body("GET", "/v2.7/me/photos").unwrap_or_default();
    if !rest.last_method_success() {
        println!("{}", rest.last_error_text());
        return;
    }

    let _ = json.load(&response_json);
    after_cursor = json.string_of("paging.cursors.after").unwrap_or_default();
}

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.  
let http = chilkat::Http::new();

// We'll cache the image data so that if run again, we don't re-download the same image again.
let num_urls = sa_photo_urls.count();
i = 0;
let url_json = chilkat::JsonObject::new();

let fac = chilkat::FileAccess::new();

while i < num_urls {
    let _ = url_json.load(&sa_photo_urls.get_string(i).unwrap_or_default());
    photo_id = url_json.string_of("id").unwrap_or_default();
    image_url = url_json.string_of("url").unwrap_or_default();

    // Check the local cache for the image data.
    // Only download and save if not already cached.
    image_bytes = fb_cache.fetch_from_cache(&image_url);
    if !fb_cache.last_method_success() {
        //  This photo needs to be downloaded.

        let sb_image_url = chilkat::StringBuilder::new();
        let _ = sb_image_url.append(&image_url);

        // Let's form a filename..
        let mut extension = ".jpg".to_string();
        if sb_image_url.contains(".gif", false) {
            extension = ".gif".to_string();
        }

        if sb_image_url.contains(".png", false) {
            extension = ".png".to_string();
        }

        if sb_image_url.contains(".tiff", false) {
            extension = ".tiff".to_string();
        }

        if sb_image_url.contains(".bmp", false) {
            extension = ".bmp".to_string();
        }

        let sb_local_file_path = chilkat::StringBuilder::new();
        let _ = sb_local_file_path.append("C:/Photos/facebook/uploaded/");
        let _ = sb_local_file_path.append(&photo_id);
        let _ = sb_local_file_path.append(&extension);

        image_bytes = http.quick_get(&image_url);
        if !http.last_method_success() {
            println!("{}", http.last_error_text());
            return;
        }

        // We've downloaded the photo image bytes into memory.
        // Save it to the cache AND save it to the output file.
        let _ = fb_cache.save_to_cache_no_expire(&image_url, "", &image_bytes);
        let _ = fac.write_entire_file(&sb_local_file_path.get_as_string().unwrap_or_default(), &image_bytes);

        println!("Downloaded to {}", sb_local_file_path.get_as_string().unwrap_or_default());
    }

    i = i + 1;
}

println!("Finished downloading all Facebook photos!");