Hello from Khoros! We hope that you, your co-workers, and your loved ones are safe and well. We're still here, so continue to reach out to us on Atlas and other channels. As always, your success is important to us.
Community 20.3 brings General Availability (GA) for Community Syndication Message List and Content Archive, as well as improvements to search, analytics, the Salesforce Connector, and the Community API. Read on to learn more.
New Features
- Community Syndication - Message List GA
- Content Archive GA
- Search enhancements
- Product Associations Analytics
- Khoros Salesforce Connector 4.2
- In-line replies and threading EA
- Updates to the Custom Tags UI in Community Admin
- Migration of videos from Ooyala to Brightcove
Community Syndication - Message List GA
Syndication Message List component. We're happy to announce that the Message List component is now in General Availability (GA). See About Message List Syndication for more information and instructions for implementation and launch.
See this blog post to learn about how we added Message List syndication to developer.khoros.com.
To recap, Message List enables you to create a read-only list of publicly accessible posts from your Community and display it on an external website. For example, you could create a list of messages from forums within a category that have a particular label applied. You could highlight blog articles that reference a specific product and put that on a product page. Mix and match from the following to define your unique message list:
- Location in the community structure
- Discussion style type, optionally filtered by attributes such as accepted solutions, featured articles, and idea status
- Label
- Product name
- Username or Rank
During the EA period, we received some very helpful EA customer feedback that led to some improvements from our initial version of this feature. (Thank you, @BekaD12!) Read on to learn more.
Feature requirements
Message List is enabled by default when you upgrade to Community 20.3. You'll find the configuration options in Community Admin > Content > Community Syndication.
As with other Community Syndication and ActiveCast components, you must enable Content Security Policy and whitelist all domains where you embed ActiveCast components, or the ActiveCast components will not render. See Enable Content Security Policy (CPS) for ActiveCast for instructions.
Dedicated skin for the Message List component
We created a new parent skin called Community Syndication. You'll find this skin in Studio > Community Style > Properties with our other parent skins.
While Community Syndication is based on Responsive Skin, it is much leaner than Responsive (we’ve reduced the overall CSS file size by ~95%, from 2.3 MB to 118KB) and using it with the Message List component dramatically improves performance and load times. You can use our default Community Syndication skin or you can create your own customized version using the Community Syndication skin as a base. We are planning to make improvements so that we can use this skin with the Community Syndication Q&A component and any future syndication components (not legacy ActiveCast).
Warning: Do not use the Community Syndication skin or a skin with Community Syndication as its parent as the skin for your entire community.
Additional filtering support for discussion styles
When you filter by the Forum, Q&A, Idea, or TKB discussion style, you can choose a Style Attribute to further filter the list of messages. Style Attributes are allowed when filtering by a single discussion style. For example, you can only select messages from forums or only from knowledge bases. (You can still use the Labels, Product, Tags, and Authors filters though.)
These are the Style Attribute options for each discussion style:
- Forum - Accepted Solutions Only
- Q&A - Accepted Solutions Only
- Ideas One of the core idea statuses. Custom idea statuses are not currently supported as a filter.
- Knowledge Base - Featured Articles Only
Content Archive GA
In the 19.10 Release Notes, we announced Early Access for the Content Archive feature. This feature is now available for GA.
You can enable the Content Archive feature from Admin > Mod Tools > Content Archive.
With Content Archive:
- Community Managers can archive a topic/article directly from the Options menu for a Forum topic, TKB, or Blog article.
- You can view all your archived contributions.
- You can Unarchive an article from the Content Archive.
- You can delete archived contents.
- The count of user stats such as # kudos, # replies etc., will remain the same post-archival of a content.
- You can provide a link to an updated/related content while archiving. Though this is optional, it is best practice to provide a related link to relevant content while archiving. For instance, if a google search result suggests content that was archived in your community and the user clicks on that link, he will be automatically redirected to the related content in your community instead. As the redirection occurs for several users, the google crawlers understand that the old link is replaced, and boost up the new link's ranking instead of the old link.
Note: The suggested URL must be a URL within your community.
Learn more about Content Archive.
Search Enhancements
With this release, we have improved the search functionality with exact phrase search and by removing “stop words” while populating the recommendation widget. Each of these are explained below.
Exact phrase search
You can now use double quotes around search terms to get search results that exactly match the phrase within the quotes. The system searches and displays results found in the message body, subject, labels, and attachments.
To activate this feature:
- Go to Admin > System > Search.
- Disable the Include punctuation while searching setting.
- Click Save.
Below example shows how the exact phrase search works:
Search for brick house (no quotes):
Say you click on Homes from the results listed. You can see that the words brick and house are searched for, but not as a single phrase or in that order.
Let’s see how exact phrase search fetches results for “brick house”:
You can see that the content Stories for Kids is listed because, it contains the phrase brick house:
Note: Exact phrase searches do not:
- support special characters (for example, "Apple&Orange" searches for "apple orange")
- display in autosuggest results
- return tags in the results
- support nested quotes (for example, “Product number “12345””)
- support multiple phrases with quotes (for example, “brick house” “sheep skin”)
Removal of common words from Recommendation Widget results
We’ve improved overall search performance by excluding commonly used words (also called “stop words”) while populating the recommendation widget. Common stop words include a, an, the, in, on.
For example, let’s say someone searches for wolf and then clicks the result Wolf in sheep’s skin:
The Recommendation Widget on the right pane suggests contents that match the words from the title, in this case Wolf, sheep’s and skin, but excludes the word in.
Hence, search is only on the primary keywords (excluding stop words) and relevant results are fetched.
Product Associations Analytics
With this release, we introduce Product Associations Analytics to measure the usage of products in your community.
Product Associations is an important Community feature as it links a brand’s e-commerce website to the Community content and vice-versa. You can improve its adoption by analyzing related metrics such as:
- The number of times a specific product is tagged to any community post
- The number of times a specific product is mentioned (using # followed by product name)in any community post
- The number of times a product is viewed on the brand domain from the product page or from a product mention
- The number of product page views when the associated product in the community page is clicked and viewed
- The number of accepted solutions in any type of community post that has a specific product association in the first post or any of the replies
A new tab called Products is listed under the CONTENT tab as shown below.
Learn more on Product-Association Analytics.
Khoros Salesforce Connector 4.2
We have addressed the open issues with Salesforce Connector 4.2. All documents and package details for Salesforce Connector 4.2 are updated.
In-line Replies and Threading EA
We had announced the EA release for In-line replies and threading in the 20.1 release. This feature is still available for EA. To participate, you must open a Support ticket and request access.
Updates to the Custom Tags UI in Community Admin
We made some minor changes to the Edit List Tag and Edit Attribute Tag modals in Community Admin. These modals appear when you click the Edit Tag button in Community Admin > Mod Tools > Custom Tags > Edit Tags.
We have updated tooltips and field names in the modal and we added the ability to view example LiQL calls. The updates do not change the functionality of custom tags. Instead, we made the updates to help developers and Community Administrators understand which custom tag data to use when retrieving custom tags and filtering messages by custom tags using the Community API. These updates coincide with improvements to the Custom Tags API described in the API Updates section of these release notes.
Migration of videos from Ooyala to Brightcove
This announcement is for communities using Ooyala Integration (Video).
Community videos uploaded after upgrading to 20.3 will be supported by BrightCove. All videos uploaded prior to 20.3 will also be migrated to BrightCove. This backend integration change is necessitated by Brightcove’s acquisition of Ooyala.
Note that there will not be any change required by community admins for this migration. Also, there will not be any change in the video uploading experience for the community members.
Support for Ooyala videos will be discontinued from June1, 2020 and if your community is not on 20.3 or above, you will not be able to use videos.
For any further clarifications, reach out to Support.
API Updates
Group Hub API changes
We have added support for setting and editing a group hub avatar via the API. Note that this changes your POST and PUT request format to the /grouphubs endpoint. Note the change from Content-Type from application/json to application/x-www-form-urlencoded.
Note: Customers who have created customizations using POST and PUT requests to the /grouphubs endpoint are advised to update their code to use the new Content-Type in the header and the new request body format.
Create a group hub with an avatar
To set or edit a group hub avatar,include the following Headers and Body Parameters in a POST (to create) or a PUT (to edit) request to the following endpoints, respectively:
- /grouphubs
- /grouphubs/<group hub id>
Headers
li-api-session-key |
[SESSION KEY] |
Authorization |
Bearer [TOKEN] |
client-id |
[CLIENT ID] |
Content-Type |
application/x-www-form-urlencoded |
Body Parameters
avatar |
The full path to the avatar image |
api.request |
A grouphub JSON object definition |
Create a new group hub with an avatar
Include the avatar parameter in the POST request body. Here is an example grouphub object for a new group hub. Place it in the api.request body parameter.
{
"grouphub":{
"id":"<internal grouphub ID>,
"title":"<display title>",
"membership_type":"<open, closed, or closed_hidden>",
"conversation_styles":[
"<string array of discussion styles included in the group hub>"
],
"parent_category":{
"id":"<optional internal ID of the parent category>"
},
"description":"<optional description of the group hub>"
}
}
cURL example (Session Key)
curl -L -X POST 'https://[COMMUNITY DOMAIN]/api/2.0/grouphubs/' \
-H 'li-api-session-key: [SESSION KEY]' \
]
-H 'Content-Type: application/x-www-form-urlencoded' \
-F 'avatar=@/PATH/TO/AVATAR/avatar.jpg' \
-F 'api.request={
"grouphub": {
"id": "shutterbugs",
"title": "Sutterbugs",
"membership_type": "closed_hidden",
"conversation_styles": [ "forum", "blog", "tkb", "idea", "qanda", "contest" ],
"parent_category": {
"id": "groupHubs"}
}
}'
cURL example (OAuth)
curl -L -X POST 'https://[COMMUNITY DOMAIN]/api/2.0/grouphubs/' \
-H 'Authorization: Bearer [TOKEN]' \
-H 'client-id: [CLIENT ID]' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-F 'avatar=@/PATH/TO/AVATAR/avatar.jpg' \
-F 'api.request={
"grouphub": {
"id": "shutterbugs",
"title": "Sutterbugs",
"membership_type": "closed_hidden",
"conversation_styles": [ "forum", "blog", "tkb", "idea", "qanda", "contest" ],
"parent_category": {
"id": "groupHubs"
}
}
}'
Updated group hub developer guides:
Edit group hub details including the avatar
Include the avatar parameter in the PUT request body. Here is an example grouphub object for an existing group hub. Place it in the api.request body parameter.
{
"grouphub":{
"title":"<display title>",
"membership_type":"<open, closed, or closed_hidden>",
"conversation_styles":[
"<string array of discussion styles included in the group hub>"
],
"parent_category":{
"id":"<optional: internal ID of the parent category>"
},
"description":"<optional description of the group hub>"
}
}
Add or edit only the avatar on an existing group hub
Include the avatar parameter in the PUT request body. Here is an example grouphub object for an existing group hub. Place it in the api.request body parameter.
{ "type": "grouphub" }
Membership API updates
As a result of customer feedback, we have finalized the Community API v2 Membership APIs with some changes. (Thank you for your patience.)
Membership API Developer Guides:
- Membership API support
- Send and accept invitations to a membership node
- Send, retrieve, approve, and deny a request to join a node
- Membership API LiQL support
We have removed the members and membership_nodes collections. These collections are no longer supported.
Membership is now handled using the nodes, users, and roles collections, and the invites and membership_requests subcollections on nodes to manage Invitations to and requests to join membership nodes.
Note: At this time, group hubs are the only nodes that support membership.
Use these endpoints on the nodes collection for the following tasks:
Endpoint |
Task |
Added |
POST |
20.1 |
|
PUT |
20.1 |
|
POST |
20.1 |
|
PUT /nodes/<node.type>:<node.id>/invites |
Accept an invitation to a membership node |
20.3 |
Membership API LiQL support
To retrieve data around memberships, membership nodes, and membership roles, you'll use LiQL queries to the users, roles, nodes and membership_requests collections. To access the data, use a GET request to the /search endpoint or use one of the FreeMarker methods that enable you to make calls to the Community API.
With LiQL you can get:
- A list of members in a membership node (i.e., a group hub)
- User details (such as join_date) for the members of a node
- User details for users with a specified membership role assigned (such as Member, Owner, or a custom membership role)
- A list of membership roles available on a node
- Data about membership roles applied to a user on a node
- A list of membership nodes to which a user belongs
- A list of pending requests to join a membership node
Note: The join_date field is not returned from a query to the users collection unless node.id is included in the WHERE clause. If the user is not a member of the node or if the node is not a membership node, the query will return null.
Note: To retrieve membership role data from a LiQL query to the roles collection, you must include node.id in the WHERE clause.
Note: A query to the nodes collection is made based on the permissions of the user making the request unless the query is constrained by user.id in the WHERE clause. When constrained by user.id, the query is made based on the permissions assigned to that user.
Note: Remember that the results of a LiQL query are dependent on the permissions of the user making the request. In other words, if a user is not allowed to see roles, roles details are not returned.
Users collection queries |
Retrieve a list of members of a specified membership node SELECT id,login FROM users WHERE node.id = '<node.type>:<node.id>' |
Retrieve user details from a membership node SELECT login, id, join_date FROM users WHERE node.id = '<node.type>:<node.id>' |
Retrieve user details for users with a specific role SELECT * FROM users WHERE roles.id ='<role prefix:node id:role title>'
|
Roles collection queries |
Retrieve a list of membership roles available on a membership node Note: If the node in the WHERE clause is not a membership node (i.e., a group hub), then the query will return the core roles on the node. SELECT * FROM roles WHERE node.id = '<node.type>:<node.id>' |
Retrieve data about a membership role applied to a user SELECT * FROM roles WHERE users.id = '<user.id>' and node.id = '<node.type>:<node.id>' |
Nodes collection queries |
Retrieve the list of membership nodes to which a user belongs SELECT join_date, title FROM nodes WHERE user.id = '32' |
Retrieve node details for nodes of a specified type (e.g., all group hubs) for a specific user Note: If user.id is not specified in the WHERE clause, then the query is made with the permissions applied to the user making the request. SELECT title,join_date FROM nodes WHERE user.id='17' AND node_type='grouphub' |
Membership_Requests collection queries |
Retrieve pending requests to join a membership node SELECT * FROM membership_requests WHERE node.id = '<node.type>:<node.id>' |
Improved custom tag API support
We have improved our API v2 custom tag API support so that you can now retrieve and set both attribute and list type custom tags. Read on to learn about the new fields and constraints to the Message and Custom_Tag objects. The improvements enable you to:
- Get messages filtered by custom tags and custom tag values
- Get custom tags filtered by message ID
Get messages filtered by custom tags and custom tag values
Get messages filtered by a custom tag with a LiQL query to the messages collection.
New fields on the messages collection
- custom_tag_scope - A custom tag key and value set on the message. This field appears in the response only when it is explicitly included in the SELECT statement and when the custom_tags.id constraint is included in the WHERE clause.
New constraints on the messages collection
- custom_tags.id - The key for the custom tag you want to filter by. When this constraint is used, custom_tag_scope is included in the response.
- custom_tags.value - Used only when filtering by a List custom tag. The value key of the List custom tag you want to filter by (e.g., messages with the Color custom tag set to Red). Can be used only when custom_tags.id is also included in the WHERE clause, and is used only when filtering the response by a list type custom tag. Use the equals operator to filter to a single value (custom_tags.value='red') or IN() to filter to multiple values (custom_tags.value IN ('red', 'blue')).
Use custom_tag_scope in the SELECT statement of a LiQL query to the Messages collection specifying the custom tag key as the value of custom_tags.id in the WHERE clause. To filter further to messages with a specific value of the tag, also include custom_tags.value in the WHERE clause.
Examples
SELECT id, custom_tag_scope FROM messages WHERE custom_tags.id = 'color'
SELECT id, custom_tag_scope FROM messages WHERE custom_tags.id = 'color' AND custom_tags.value = 'red'
SELECT id, custom_tag_scope FROM messages WHERE custom_tags.id = 'color' AND custom_tags.value IN ('red', 'blue')
The response includes a custom_tag_scope field (a custom_tag_message_scope object) that includes the value and the display text of the custom tag assigned to the message.
custom_tag_scope for a list custom tag
"custom_tag_scope" : {
"type" : "custom_tag_message_scope",
"value" : "green",
"text" : "Green"
}
custom_tag_scope for an attribute custom tag
"custom_tag_scope" : {
"type" : "custom_tag_message_scope",
"value" : "true",
"text" : "true"
}
Get custom tags filtered by message ID
Get custom tags for a specific message with a LiQL query to the custom_tags collection.
New field on the custom_tags collection
- message_scope - The custom tag value and display text for a custom tag applied to the specified message. You must explicitly include message_scope in the SELECT statement and the messages.id constraint in the WHERE clause of a LiQL query to include message_scope in the response.
- possible_values - The possible values for a List custom tag. Not used with Attribute custom tags. This field is not returned by default. You must specifically include it in the SELECT statement.
Example
SELECT id, text, message_scope FROM custom_tags WHERE messages.id = '1267'
message_scope for a list custom tag
"message_scope" : {
"type" : "custom_tag_message_scope",
"value" : "white",
"text" : "White"
}
message_scope for an attribute custom tag
"message_scope" : {
"type" : "custom_tag_message_scope",
"value" : "true",
"text" : "true"
}
New Custom Tag Developer Guides
See these new guides in the Developer Doc Portal:
- Custom Tag API support
- Return whether any posts have specific custom tag
- Get messages with a given custom tag applied
- Get custom tags on a given message
- Set or update a custom tag on a message
You Found It. We Fixed It.
- We have fixed the issue where customers could not delete an attachment when editing a message.
- We have fixed the issue where images in Boards, Blogs, and TKBs were being mistakenly converted to data-lia-image tag when certain custom plug-ins were used in the message editor. This transformation no longer occurs and the images render properly.
- We have fixed the issue where users could download but not preview images in forums, blogs, and TKBs.
- Previously, unexpected errors were being thrown on the Community Analytics Members > Value Analytics page. This issue has been fixed.
- We have fixed the issue where search produced intermittent, unexpected errors when search pagination was enabled.
- Previously, the common.widget.slide-out-nav-menu sporadically showed different nodes for authenticated members. Now, the slide-out menu consistently displays the nodes you have permission to access.
- Previously, when posting multiple replies to forum posts at the same time, file attachments were added to the wrong post if the replies were autosaved. This issue has been fixed.
- Previously, when a user sorted topics by the newest to oldest (newest posts are listed first) and attempted to access page 1 of a group topic either by clicking page 1 or by viewing the group itself and clicking on the topic title, they were redirected to the last page in the topic list. As a result, the most recent X number of posts could be inaccessible depending on how the UI is configured. This behavior has been fixed and users can now access page 1 of the sorted topic list and see the most recent posts in the thread.
- We have fixed the issue on AWS-hosted communities where any request taking longer than 60 seconds displayed a Cloudfront timeout error.
- Previously, creating an anchor to a specific part of the page using the Link/Unlink button in the message editor added an additional "http://" to the URL rendering the link useless. This issue has been fixed and now anchor tags are coded properly and work as expected.
- When exporting large Community Analytics reports against AWS-hosted communities, sometimes 504 gateway errors were thrown and the report process was cancelled. This issue had been fixed and reports now export fine.
- Previously, if a message has been edited, further edits done to that same message using API V2 would not be successful in specific scenarios. This issue has been fixed.
- In API V2, the query SELECT * FROM users WHERE online_status = 'online' was producing duplicate results. This issue has been fixed and now each online user is returned only once.
- We have fixed the issue where users were not able to schedule Page View reports from Community Analytics. Additionally, we have fixed other problems related to the creation, management, and delivery of scheduled reports.
- We have fixed various issues relating to user data not getting properly synced with their corresponding Salesforce records.
- Previously, there was a link to the Group Hub names under the membership tab. Now, they are not clickable.
- Previously, you could view the membership tab when you drill down to group hubs. Now, we have replaced it with the member tab.