Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
BedrockMission!

Learn more

View all

Sign in to view all badges

SOLVED

API - Is there a way to retrieve the data of a social component in a structured way?

matthieu_théria
Level 2
Level 2

Hi,

I have not found how to do what I want in the AEM documentation or in a tutorial...

Is there a way to retrieve the data of a social component in a structured way? I know that I can retrieve specific nodes in the repository, but I need to figure out how the social component is implemented in the repository (nodes structure).

Is it possible to get the forum and its posts for example. What would be the best method to do this (JCR API, Sling, AEM API)?

Thanks,

Matthieu

1 Accepted Solution
PuzanovsP
Correct answer by
Community Advisor
Community Advisor

Hi Matthieu,

You can use Query Builder to retrieve all forums.(http://docs.adobe.com/docs/en/aem/6-0/develop/search/querybuilder-api.html)

type=cq:PageContent
property=cq:template
property.value=/apps/aaa/greater/templates/new-community

Would return you paths to the forums within the website.

To find out every component under certain path, again you can use query builder to select certain resources under known path.

e.g. 

type=cq:PageContent
property=cq:template
property.value=/apps/aaa/greater/templates/my-topic
path=/path/to/my-forum

Once you retrieve paths to your individual items(forums, posts or topics) you can call adaptTo method to adapt resource from path to your desired component. You already have adapters for forums and posts provided with out of the box AEM 6. (http://localhost:4502/system/console/status-adapters).

Thanks,

Peter

View solution in original post

12 Replies
kalyanar
Employee
Employee

what version of AEM and what social components(jsp or handlebars) are you using

PuzanovsP
Community Advisor
Community Advisor

Yes, it's possible to view data as strucktured json. Your API in this case would be a wget request to the corresponding component path as json.

For example data displayed on https://communities.adobe.com(who also use social component) can be viewed by adding json selector at the end of the url.

https://communities.adobe.com/content/dam/cush/aem_technologistsdevelopersarchitects/Ask-AEM-Communi... shows you the structure used on the communities website.

Thanks,

Peter

matthieu_théria
Level 2
Level 2

Hi Kalyanar,

I have the AEM version 6.0 and I currently make my tests with the Geometrixx samples to discover the possibilities.

Matthieu

matthieu_théria
Level 2
Level 2

Hi Peter,

Thanks for your reply.

I see that I can get the structure in JSON, but the data is very "raw".

There is no way to get this data from an API in a more structured way. For example, to retrieve all forums, and for a specific forum, retrieve all topics and posts?

I need to understand how to parse this JSON to extract what I need? An also need to a the exact path of this forum?

Thanks,

Matthieu

kalyanar
Employee
Employee

Hi Matthieu, 

Check http://localhost:4502/content/community-components/en/comments/jcr:content/content/comments.social.j...

Community-components is the recommended way to use socos. Some geometrixx soco examples are based on jsps. Please refer to community-components. Also This url gets you a very clean json.

PuzanovsP
Correct answer by
Community Advisor
Community Advisor

Hi Matthieu,

You can use Query Builder to retrieve all forums.(http://docs.adobe.com/docs/en/aem/6-0/develop/search/querybuilder-api.html)

type=cq:PageContent
property=cq:template
property.value=/apps/aaa/greater/templates/new-community

Would return you paths to the forums within the website.

To find out every component under certain path, again you can use query builder to select certain resources under known path.

e.g. 

type=cq:PageContent
property=cq:template
property.value=/apps/aaa/greater/templates/my-topic
path=/path/to/my-forum

Once you retrieve paths to your individual items(forums, posts or topics) you can call adaptTo method to adapt resource from path to your desired component. You already have adapters for forums and posts provided with out of the box AEM 6. (http://localhost:4502/system/console/status-adapters).

Thanks,

Peter

View solution in original post

matthieu_théria
Level 2
Level 2

Hi Kalyanar,

I check this link, I see an interesting JSON, but I'm not sure to understand how I can retrieve the forum and its posts for example.

Could you give some hints?

Thanks,

Matthieu

matthieu_théria
Level 2
Level 2

Thanks Peter,

I will experiment this.

Matthieu

kalyanar
Employee
Employee

Please find below a sample that queries for posts posted after a given time. This is just a sample that i wrote to explain to you.

package com.adobe.acs.commons.soco.servlets;

import com.adobe.cq.social.commons.client.api.SocialComponent;
import com.adobe.cq.social.commons.client.api.SocialComponentFactory;
import com.adobe.cq.social.commons.client.api.SocialComponentFactoryManager;
import com.adobe.cq.social.ugc.api.*;
import com.adobe.cq.social.ugcbase.SocialResourceUtils;
import com.adobe.cq.social.ugcbase.SocialUtils;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.result.Hit;
import com.day.cq.search.result.SearchResult;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.felix.scr.annotations.*;
import org.apache.felix.scr.annotations.Properties;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.*;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;

import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
@Service
@Properties({
        @Property(name = "service.description",
                value = "com.adobe.acs.commons.servlets.SampleJSONServlet"),
        @Property(name = "sling.servlet.resourceTypes", value = {"sling/servlet/default"}, propertyPrivate = true),
        @Property(name = "sling.servlet.methods", value = {HttpConstants.METHOD_GET}, propertyPrivate = true),
        @Property(name = "sling.servlet.selectors", value = {"sample"}, propertyPrivate = false),
        @Property(name = "sling.servlet.extensions", value = {"json"}, propertyPrivate = false)})
public class SampleJSONServlet extends SlingSafeMethodsServlet {
    @Reference
    private SocialUtils socialUtils;
    @Reference
    private SocialComponentFactoryManager socialComponentFactoryManager;

    @Reference
    private UgcSearch ugcSearch;

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        String lastreloadtime = request.getParameter("lrt");
        if("undefined".equals(lastreloadtime)){
            lastreloadtime=null;
        }

        JSONObject obj = new JSONObject();
        JSONArray arr = new JSONArray();
        final ResourceResolver resolver = request.getResourceResolver();
        final Session session = resolver.adaptTo(Session.class);
        PageManager pageManager = resolver.adaptTo(PageManager.class);
        Page page = pageManager.getContainingPage(request.getResource());
        List<SocialComponent> hits = new ArrayList<SocialComponent>();
        try {
            Resource resource = request.getResource();
            if(request.getParameter("lrt")!=null) {
                final UgcFilter ugcFilter = getFilter(request, page.getPath());
                if (ResourceUtil.isSyntheticResource(resource)) {
                    page = pageManager.getContainingPage(resource);
                } else if (SocialResourceUtils.isSocialResource(resource)) {
                    final ValueMap vm = resource.adaptTo(ValueMap.class);
                    final String rootResource = vm.get(SocialUtils.PN_CS_ROOT, "");
                    page = pageManager.getContainingPage(rootResource);

                }
                final SearchResults<Resource> results = ugcSearch.find("ugc-sc", resolver, ugcFilter, 1, 10000);
                for (final Resource res : results.getResults()) {
                    if (res != null) {
                        try {
                            final SocialComponentFactory factory = socialComponentFactoryManager.getSocialComponentFactory(res);


                            SocialComponent component = (factory != null) ? factory.getSocialComponent(res, request)
                                    : null;
                            if (component != null) {
                                arr.put(new JSONObject(component.toJSONString(false)));
                            }
                        } catch (Exception e) {

                        }
                    }
                }
            }
            obj.put("items", arr);
            SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
            Date date1 = new Date();

            obj.put("lastreloadtime",  dateFormatGmt.format(new Date()));
            response.setContentType("text/json");
            obj.write(response.getWriter());
        } catch (ParseException e) {
            //e.printStackTrace();
        } catch (RepositoryException e) {
           // e.printStackTrace();
        } catch (JSONException e) {
            //e.printStackTrace();
        }catch(Exception e){
           // e.printStackTrace(System.out);
            e.printStackTrace(response.getWriter());
        }
    }

    private UgcFilter getFilter(SlingHttpServletRequest request,String path) throws ParseException {
        final UgcFilter ugcFilter = new UgcFilter();
        final ConstraintGroup pathFilters = new ConstraintGroup();

        PathConstraint pathConstraint = new PathConstraint(path, PathConstraintType.IsDescendantNode,Operator.And);
        pathFilters.and(pathConstraint);
        SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
        dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
        String ltr= request.getParameter("lrt");
        ValueConstraint<Long> valueConstraint  = new ValueConstraint<Long>(SocialUtils.PN_DATE,dateFormatGmt.parse(ltr).getTime(),ComparisonType.GreaterThan);
        pathFilters.and(valueConstraint);
        ugcFilter.and(pathFilters);
        return ugcFilter;
    }
}

matthieu_théria
Level 2
Level 2

Hi Kalyanar,

Thanks for the sample, I will try it in my environment.

Two questions:

  1. In your sample, I will need to call this servlet by calling something like a PATH.sample.json. What will be the PATH of the resource in this case? For example, in the Geometrixx demo, it will work on what kind of resources?
  2. I don't understand the link between between the selector 'social' (http://localhost:4502/content/community-components/en/comments/jcr:content/content/comments.social.j...)and this sample?

Thanks for your help!

Matthieu

matthieu_théria
Level 2
Level 2

Hi Kalyanar,

I have tried and modified your sample for my needs. It works! Thanks for your help.

If  I traverse all nodes in the path "mywebsite/content", is it possible to determine if a page or a page content uses a social component?

Thanks,

Matthieu

kalyanar
Employee
Employee

It will work for any path wiht this selector.