Viewed   150 times

Now I posting a single photo to wall like this:

$response = $facebook->api("/$group_id/photos", "POST", array(
    'access_token=' => $access_token,
    'message' => 'This is a test message',
    'url' => 'http://d24w6bsrhbeh9d.cloudfront.net/photo/agydwb6_460s.jpg',
   )
);

It works fine, but can I somehow post a multiple photos, something like this:

 Answers

5

You can make batch requests as mentioned here: https://.com/a/11025457/1343690

But its simple to loop through your images and publish them directly.

foreach($photos as $photo)
{
       //publish photo
}


Edit:

(regarding grouping of photos on wall)

This grouping is done by facebook automatically if some photos are uploaded into the same album.

Currently you cannot create an album in a group via Graph API - it is not supported (as of now), see this bug.

But you can do this - create an album manually, then get the album_id by-
GET /{group-id}/albums, then use the the code with album_id instead of group_id-

foreach($photos as $photo){
   $facebook->api("/{album-id}/photos", "POST", array(
      'access_token=' => $access_token,
      'name' => 'This is a test message',
      'url' => $photo
      )
   );
}

I've tested it, see the result-

Thursday, December 22, 2022
3

The path you are using /406221796071956/photos is wrong and that's why it does not work.

The reason that this path is wrong, is that 406221796071956 is the id of a picture, see for yourself, the Graph API Explorer for 406221796071956 says:

"type": "photo"

If you want to publish to that album then use /196878530339618/photos, since it's the album: Graph API Explorer for 196878530339618

"type": "album"


Edit

Please refer to https://developers.facebook.com/docs/reference/api/album/#photos for adding photos to an album.


2nd Edit

According to the documentation of the Album object:

can_upload

Determines whether the UID can upload to the album and returns true if the user owns the album, the album is not full, and the app can add photos to the album

So you need the album not to be full, to be the owner of the album and have the right permissions for uploading.

Monday, September 12, 2022
 
2

I've verified using the Graph API explorer that the pagination is not working as you have described. Log it as a bug with Facebook at: https://developers.facebook.com/bugs and post the bug # here.

EDIT

Per the bug closure, the 100 limit is By Design and you won't get more than that, meaning that Facebook has made a conscious business decision to limit the amount of data it has to store, process, and serve from the Graph API. It costs money to do so and since the API is free to use, I can't argue with them. However, if I was paying for it, then hell yes I kick and scream all the way down the road.

Tuesday, August 30, 2022
 
sigge
 
2

You can do it by passing the following items in the array:

'name' => "post title",
'link' => "url to the page",
'message'=> "message",
'description' => "longer description",
'picture'=>"url of the picture",
'caption' => "Another bit of text"

This removes any reliance on the FB scraper to go out to the url and scrape and parse the data.

Sunday, August 7, 2022
 
4

WebScrapperController.java

package com.stackovertwo.stackovertwo;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
//import org.w3c.dom.Document;
//import org.w3c.dom.DocumentFragment;
import org.jsoup.nodes.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RestController
public class WebScrapperController {

    @GetMapping("/")
    public String index() {
        return "Greetings from Spring Boot!";
    }
    
//  @Autowired
//    private RestTemplate restTemplate;
    @Autowired
    WebScrapperService webScrapperService;

    List<String> websites = Arrays.asList("https://pizzerijalimbo.si/meni/", 
        "https://pizzerijalimbo.si/kontakt/", 
        "https://pizzerijalimbo.si/my-account/", 
        "https://pizzerijalimbo.si/o-nas/");

    @GetMapping("/podatki")
    public ResponseEntity<Object> getData(@RequestParam(required = true) int numberOfWebsites) throws InterruptedException, ExecutionException {
        List<SiteResponse> webSitesToScrape = new ArrayList<>();
//        List<String> websitesToScrape = websites.subList(0, numberOfWebsites);
        List<SiteResponse> responseResults = new ArrayList<SiteResponse>();
        CompletableFuture<SiteResponse> futureData1 = webScrapperService.getWebScrappedContent(websites.get(0));
        CompletableFuture<SiteResponse> futureData2 = webScrapperService.getWebScrappedContent(websites.get(1));
        
        //CompletableFuture.allOf(futureData1, futureData2).join();
        webSitesToScrape.add(futureData1.get());
        webSitesToScrape.add(futureData2.get());
        
        List<SiteResponse> result = webSitesToScrape.stream().collect(Collectors.toList());
        return ResponseEntity.ok().body(result);
    }

}

WebScrapperService.java

package com.stackovertwo.stackovertwo;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.CompletableFuture;

@Service
public class WebScrapperService {
    @Autowired
    private RestTemplate restTemplate;
    
    Logger logger = LoggerFactory.getLogger(WebScrapperService.class);

    @Async
    public  CompletableFuture<SiteResponse> getWebScrappedContent(String webSiteURL) 
            //throws InterruptedException 
        {
        logger.info("Starting: getWebScrappedContent for webSiteURL {} with thread {}", webSiteURL, Thread.currentThread().getName());
        HttpEntity<String> response = restTemplate.exchange(webSiteURL,
                HttpMethod.GET, null, String.class);
        //Thread.sleep(1000);
        SiteResponse webSiteSummary = null ;
        String resultString = response.getBody();
        
        HttpHeaders headers = response.getHeaders();
        int statusCode = ((ResponseEntity<String>) response).getStatusCode().value();
        System.out.println(statusCode);
        System.out.println("HEADERS"+headers);
        try
        {
            Document doc = (Document) Jsoup.parse(resultString);
            Elements header = doc.select(".elementor-inner h2.elementor-heading-title.elementor-size-default");
            System.out.println(header.get(0).html());
            // Return the fragment.
            webSiteSummary = new SiteResponse(statusCode, header.get(0).html());
            
        }
        catch(Exception e) {
            System.out.println("Exception "+e.getMessage());
        }
        logger.info("Complete: getWebScrappedContent for webSiteURL {} with thread {}", webSiteURL, Thread.currentThread().getName());

        return CompletableFuture.completedFuture(webSiteSummary);
    }
    
}

SpringBootApp.java

package com.stackovertwo.stackovertwo;

import org.springframework.boot.SpringApplication;    
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate; 

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

//import javax.net.ssl.HostnameVerifier;
//import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
//import javax.net.ssl.SSLSession;
//import javax.net.ssl.TrustManager;
//import javax.net.ssl.X509TrustManager;
//import javax.security.cert.X509Certificate;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.*;
import org.apache.http.conn.ssl.*;

@SpringBootApplication    
public class SpringBootApp  
{  
    public static void main(String[] args)  
    {    
        SpringApplication.run(SpringBootApp.class, args);    
    }   
    
    @Bean
    public RestTemplate restTemplate() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;

        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
                        .loadTrustMaterial(null, acceptingTrustStrategy)
                        .build();

        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);

        CloseableHttpClient httpClient = HttpClients.custom()
                        .setSSLSocketFactory(csf)
                        .build();

        HttpComponentsClientHttpRequestFactory requestFactory =
                        new HttpComponentsClientHttpRequestFactory();

        requestFactory.setHttpClient(httpClient);
        
        //return new RestTemplate();
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }
    
}  

Note: I disabled SSL verification while calling the webulr in resttemplate, but its not recommendd inproduction (For assignment its ok). But you need to import the keys via java keystore in case production : https://myshittycode.com/2015/12/17/java-https-unable-to-find-valid-certification-path-to-requested-target-2/

Wednesday, September 28, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :