Blog Post

Release Notes
10 MIN READ

Khoros Communities 20.1 Release Notes

AshaC's avatar
AshaC
Khoros Staff
5 years ago

New Features

Update to the Khoros Communities release schedule

Khoros Communities is moving away from a monthly release cadence and a staggered upgrade system. Starting with the next release, we are moving to a 6-week release cycle with a 100% upgrade target. We believe this new release cadence will improve overall quality, value in each release, and innovation. 

We are keeping the same “year.month” release-naming scheme. For example, the next Community release, which all customers will receive, will arrive in March and be called the 20.3 Release.

We value all our Khoros Community customers and appreciate your patience as we roll out this new system and any minor bumps we might incur during this change.

Learn more about this change. As always, your feedback is always welcome. 

Content Archive (EA)

In the 19.10 Release, we announced the Early Access release of Content Archive. With this feature, Community Managers can archive a topic/article directly from the Options menu for each Forum topic, TKB, or Blog article.  

To enable the Content Archive feature community admins can go to Admin > Mod Tools > Content Archive.


The My Archived Contributions option appears under My Profile > Topics I’ve Participated in component when Display “My Archived Contributions” on member profile pages is granted to the member. Here, members can view all their archived contributions.


 

 



Use the Content Archive feature to ensure that fresh and relevant content shows up in your community. Moving outdated or low-use content to the archive can help improve the findability of more critical community content.

With the 20.1 Release, the Content Archive EA includes some new features. 

As the contents of the archive grows over time, it becomes more difficult to find the specific article you want. For quick retrieval, use the search options available under Archives in your community.

Note: Archived contents can be accessed only by permissioned community members (primarily Community Admins/Moderators). 

Content Archive analytics

With the 20.1 release of Content Archive, we now include Content Archive metrics.  Archived Content metric measures the number of contents archived. These new metrics are available in Community Analytics > Content and Community Analytics > Moderators.

Learn more about the Content Archive feature.

Learn about Content Archive API support below.

Inline Replies and Threading (EA)

To better organize discussions and keep context meaningful, we have introduced an Inline Replies and Threading feature. With Inline replies, you can reply to another reply and continue the discussion in a separate, single thread.  

Note: To participate in the In Replies and Threading EA, you must open a Support ticket and request access.

Note: By default a post or a reply has 5 levels of threaded(indented) replies. Any reply after the fifth reply would be at the same level of indentation as the fifth reply. This is configurable upto 8 levels. Contact support to configure the levels of indentation.

By default, the community setting to display posts is set to Linear Format. Please edit this setting on the Discussion Styles > Posts & Topics > Topic Display tab to enable threading.

Enable Forums Version 5

You must upgrade Forums to Version 5 to enable Inline Replies and Threading. 

  1. Go to Studio > Features.
  2. In the Forums drop-down list, select 5.

  3. Click Save.


Learn about quilt changes for forums that are customized according to community needs.

Learn more about the Inline Replies and Threading feature

Additional leaderboard filters

We have introduced a new time filter (The last 3 Months) in both the Kudos & Accepted Solutions tabs. Also, under the Accepted Solutions, you will now see the Time Range options in sync with the options available under the Kudos tab.

To change the time range filter for Kudos or Accepted Solutions leaderboard components for 3 months:

  1. Go to Community Admin > Features.
  2. Click Kudos or Accepted Solutions on the left pane.

3. Set the time range option to The last 3 Months.

4. Click Save.

Learn more about Kudos and Accepted Solutions

Community Syndication: Message List EA update

In the 19.10 Release, we announced the Community Syndication Message List feature and we’re excited to share some new functionality. 

You can now display content in a Card View similar to what you might see on your .com blog announcements.

This enables you to include images from the community as part of the message, creating more visually engaging content to bring users into the community. Toggle back and forth between List View and Card View to refine the look and feel of your Message List using the configuration panel and see the content updated in real-time in the preview window. 

Additionally, you can now select content from across multiple categories to be viewed in a single Message List. 

  • Refine the list of messages by selecting a single discussion style like blogs or select multiple discussion styles (forums, TKBs, blogs or ideas) into a single list. 
  • Curate the content by choosing one or multiple tags, labels, or authors to keep in control of what to display. 
  • If you’ve imported your product catalog into community and want to bring community content about a specific product into your e-commerce experience, you can pull the content tagged with a product association to refine content only about that specific product.

We are finishing up analytics for this feature as well as doing some final performance testing prior to releasing the feature as Generally Available. If you are interested in learning more, send a private message to RayC

API Updates

We've added API support for:

  • Group Hubs
  • Node Memberships
  • Content Archival

Group Hubs API

We've added Community API v2 Create, Update, and Delete support for group hubs. Perform actions involving membership (such as viewing members of a group hub, inviting users, and managing requests to join) using the Membership APIs.

Examples

Create a group hub

curl -X POST \
https://[COMMUNITY DOMAIN]/api/2.0/grouphubs \
-H 'Content-Type: application/json' \
-H 'li-api-session-key: [SESSION KEY]' \
-d '{
"grouphub": {
"id": "shutterbugs",
"title": "Shutterbugs",
"membership_type": "closed_hidden",
"conversation_styles": [ "forum", "blog", "tkb" , "idea",
"qanda", "contest" ],
"parent_category": {
"id": "groupHubs"
}
}
}'

Edit a group hub

curl -X PUT \
  https://[COMMUNITY DOMAIN]/api/2.0/grouphubs/shutterbugs \
  -H 'Content-Type: application/json' \
  -H 'li-api-session-key: [SESSION KEY]' \
  -d '{
        "grouphub": {
           "description": "A place where we can talk photography."
        }
}'

Delete a group hub

curl -X DELETE \
  https://[COMMUNITY DOMAIN]/api/2.0/grouphubs/shutterbugs \
  -H 'li-api-session-key: [SESSION KEY]

Get group hub details

GET calls are made using the /search endpoint with a LiQL query passed as the value of the q parameter.

curl -X GET \
'https://[COMMUNITY DOMAIN]/api/2.0/search?q=SELECT+topics.count%28%2A%29+FROM+grouphubs+WHERE+id+%3D+%27knittingGroupHub%27' \
  -H 'li-api-session-key: [SESSION KEY]'

 

  • Make LiQL queries to the v2 grouphubs collection to get details about a group hub, such as the group hub's parent and location in the community structure, and the count of topics and messages in the group hub. 
  • Make queries to the V2 messages collection to get message details. You can also use calls on the v1 Message and MessageDiscussion objects.
  • Make queries the v2 nodes collection to get a group hub's child nodes or to get a list of group hubs in the community or within a category. You can also use calls on the v1 GenericNode object. 
  • Make queries to the v2 subscriptions collection for group hub subscription information. You can also use calls on the v1 Subscription object.
  • Make queries to the v2 boards collection for information about a child board in a group hub. You can also use calls on the v1 Board object.
  • Make queries to the membership_requests collection create a request to join and to accept or deny a request to join

LiQL examples

These example queries will get you started with some common group hub tasks.

Get the count of topics on a group hub

SELECT topics.count(*) FROM grouphubs WHERE id = 'knittingGroupHub'

Get the last 5 messages posted to a group hub

SELECT subject,body, author,href,view_href FROM messages WHERE grouphub.id = 'knittingGroupHub' ORDER BY post_time DESC LIMIT 5

Get the details about a group hub's child nodes

SELECT id,title,href,view_href FROM nodes WHERE parent.id = 'grouphub:knittingGroupHub' ORDER BY message_activity.core_property_change_time

Get a list of group hubs in a category

SELECT id,title,view_href,href FROM nodes WHERE parent.id = 'category:groupHubs'

More to come

Look for the ability to set the group hub avatar via the API in the next release.

Membership APIs

Membership nodes are nodes that have members, membership roles, and optional access restrictions. At this time, a group hub is the only node type that supports membership.

We've added new Community API v2 collections to support membership actions.

Important! We have deprecated the memberships collection introduced during Group Hubs EA. The memberships collection supported retrieving join date, node, and user details associated with a specific membership. The memberships collection is deprecated as of Community release 20.1. Retrieve membership details using the membership_nodes and members collections as described below. 

Note: We discovered issues with the members and membership_nodes collections soon after the release of 20.1. We will be replacing these collections with new fields and constraints on the users and nodes collections to retrieve members of a node and the nodes to which the user is a member.

Collection

Object

Actions

Supported tasks

membership_requests

membership_request

GET



POST

PUT

Retrieve requests to join a membership node. Must be constrained by node ID.


Send a request to join


Approve or deny a request to join

invites

invite

POST

Send invitations to join a membership node

Examples

Retrieve requests to join a membership node

SELECT * FROM membership_requests WHERE node.id = 'grouphub:developerNetwork'

Retrieve requests to join a node 

SELECT * FROM membership_requests WHERE node.id = 'grouphub:developerNetwork'

Send a request to join a membership node

URL: /api/2.0/nodes/<node.id>/membership_requests
Method: POST

Body:
{
  "data" : {
    "type" : "membership_request"
   }
}

cURL example

curl -X POST \
  https://[COMMUNITY DOMAIN]/api/2.0/nodes/<node_type>:<node_id>/membership_requests
  -h 'Content-Type: application/json' \
  -h 'li-api-session-key: [SESSION KEY]' \
  -d '{
     "data" : {
           "type" : "membership_request"
       }
  }'

 

Approve or deny  a request to join

URL: /api/2.0/nodes/<node_type>:<node_id>/membership_requests
Method: PUT

Body:
{
  "data" : {
    "type" : "membership_request",
    "approve_request" : "<true or false>",
    "user_id" : <ID of the user who requested to join>
   }
}

cURL example to approve

curl -X PUT \
  https://[COMMUNITY DOMAIN]/api/2.0/nodes/<node.id>/membership_requests
  -h 'Content-Type: application/json' \
  -h 'li-api-session-key: [SESSION KEY]' \
  -d '{
    "data":{ 
      "type":"membership_request",
      "approve_request":"true",
      "user_id":2
    }
  }'

 

cURL example to deny

curl -X PUT \
  https://[COMMUNITY DOMAIN]/api/2.0/nodes/<node.id>/membership_requests
  -h 'Content-Type: application/json' \
  -h 'li-api-session-key: [SESSION KEY]' \
  -d '{ 
    "data":{ 
      "type":"membership_request",
      "approve_request":"false",
      "user_id":2
    }
  }'

 

Send invitations to join a membership node

URL: /api/2.0/nodes/<node_type>:<node_id>/invites
Method: POST

Body:

  "data":{ 
    "type":"invite",
    "invitees":[ 
      { 
        "id":<id of first person to invite>
      },
      { 
        "id":<id of next person to invite>
      },
      {
     ..
      }
    ],
    "role":{ 
      "name":"<membership role title. Member is default>"
    },
    "body":"Please Join My GH"
  }
}

cURL example

curl -X POST \
https://[COMMUNITY DOMAIN] /api/2.0/nodes/<node.id>/invites
-h 'Content-Type: application/json' \
-H 'li-api-session-key: [SESSION KEY]' \
-d ‘{ 
  "data":{ 
    "type":"invite",
    "invitees":[ 
      { 
        "id":5
      },
      { 
        "id":6
      }
    ],
    "role":{ 
      "name":"Owner"
    },
    "body":"Please Join My GH"
  }
}'

More to come

Stayed tuned for API support for the following tasks in the next release:

  • Accepting an invitation to a membership node
  • Removing and assigning roles from/to members in a membership node

Content Archive API

We've added API support for Content Archive. The Content Archive API supports:

  • Archiving a message
  • Updating an archived message (adding or updating a suggested URL)
  • Removing a message from the archive
  • Retrieving archived content

Archive a message

URL: /api/2.0/archive

curl -X POST \
  https://[COMMUNITY DOMAIN]/api/2.0/archives/archive \
  -H 'Content-Type: application/json' \
  -H 'li-api-session-key: [SESSION KEY]' \
  -d '[{
"messageId" : "251",
"suggestedUrl" : "<full URL to suggested content>"
}]'

Edit an archived message

URL: /api/2.0/archives/suggestedUrl

Method: PUT

curl -X PUT \
https://[COMMUNITY DOMAIN]/api/2.0/archives/suggestedUrl \

  -H 'Content-Type: application/json' \
  -H 'li-api-session-key: [SESSION KEY]' \
  -d '[{
"messageId" : "251",
"suggestedUrl" : "<full URL of suggested content>"
}]'

Remove a message from the archive

URL: /api/2.0/archives/unarchive

Method: POST

curl -X POST \
https://[COMMUNITY DOMAIN]/api/2.0/archives/unarchive \

  -H 'Content-Type: application/json' \
  -H 'li-api-session-key: [SESSION KEY]' \
  -d '[{
"messageId" : "251" 
}]'

 

Retrieve archived content

URL: /api/2.0/search?q=<LiQL query>

Method: GET

curl -X GET \
'https://[COMMUNITY DOMAIN]/api/2.0/search?q=SELECT%20id%2C%20author%2C%20subject%20FROM%20messages%20WHERE%20visibility_scope%20%3D%20%27public%27%20AND%20author.login%20%3D%20%27User2%27' \
  -H 'li-api-session-key: [SESSION KEY]' 

 

When retrieving messages, you can filter by visibility_scope in the WHERE clause of a query to the messages collection.

  • To include archived content along with public content, use a visibility_scope of public_and_archived.
  • To retrieve only archived content, use a visibility_scope of archived.

Example LiQL queries

select id, author, subject from messages where visibility_scope = 'public_and_archived' AND author.login = 'User2'

select id, author, subject from messages where visibility_scope = 'archived' AND author.login = 'User2'

You Found It. We Fixed It.

  • When creating a new case via the Case Portal, some members reported receiving an error message and being instructed to correct the highlighted fields and resubmit the request. However, no fields in the form were highlighted. Additionally, sometimes the case was created and other times it was not. Both of these issues have been fixed.
  • We have fixed the issue where the Community Batch API with Post JSON was not returning any users for some communities.
  • Previously, there were some discrepancies between the results for the /users/id/<user id>/posts and /users/id/<user id>/posts/count REST API v1 calls. Now, these calls produce consistent results.

 

Updated 6 months ago
Version 12.0
  • RayC  sounds great, I would like to join definitely.

    You presented this Message List Syndication for me earlier, I thought there might be possibility to scope to a specific topic-id by now 🙂 But I think that label / tag filter would work with us as well. 

  • The threaded topics is still unclear. There's not a concrete example of what it will look like when someone replies. Is it indented within the same topic still? What does it mean when you say it'll be a separate thread?

  • Aren't all of the "-h" flags for the curl command in the Membership APIs section supposed to be "-H"?

  • AshaC we already have threaded replies set & working, & our design incorporates it. So I'm trying to understand exactly what's actually changing here because it's not really clear to me.

  • Some of these API calls use

    li-api-session-key

    and some use

    lia-api-session-key

     ("li" vs. "lia") for the header to send the session key. Is that correct, or should they all be the same (which is the correct one, then)?

    Additionally, the value sent for this header: should it include the "<value type="string"></value>" markup provided by the authentication session endpoint, or just the value between those tags?