Lab / Idea / Unconference Meetup?
I have a couple things on my community backlog that probably require some level of customization - I tend to be looking for stuff in Atlas that already has some traction or headway AND I see lots of "under consideration" ideas AND I see lots of "Did anybody make an XYZ widget in their community..." questions BUT what I haven't yet found (beyond this forum itself) is an available time and place for Devs to get together on their own and either attack a specific common problem OR talk together through a top of mind issue. It could be anything from a KhorosLed affair or even just an Unconference we put on ourselves. Would be REALLY great if there was a vanilla lab stood up to do actual live-action work that participants could then try to leverage in their own environments later. Am I just not finding this yet? Do we need to bootstrap something? BlakeH - has this come up before?3.2KViews
Sign in to react to this post26Comments
Subscriptions to a label?
Hi all, I'm attempting to get the list of people who have subscribed to a label, but am struggling. The documentation is a bit confusing: It says both that you have to use a community ID as the node.id constraint but also that you can give the node.id constraint as a board id? Seems conflicting. And, regardless of the documentation, I get an error when I try to use a board ID (such as node.id='board:wireless-lan' where wireless-lan is the id of the board) My user has full admin permissions. Any ideas? I am not really a developer (as is probably evident!), just trying to pull a few bits of data for a stakeholder. Thanks!Solved2.6KViews
Sign in to react to this post9Comments
I have been playing around for half an hour now and also only get subscriptions for the current user :( The target.id param seems to be always causing an error and therefor going against how it's documented even though it is returned in the resultset.
Sign in to react to this post
Can someone walk me through authenticating and using Postman with Aurora?
I'm a bit of a newbie when it comes to GraphQL and Postman and I'm struggling to work through the dev docs when it comes to authenticating and setting up the basics in Postman for testing in API calls in Aurora. We're looking ahead to migration and want to start getting familiar with basic API calls. Has anyone successfully got Postman and Aurora working? Is anyone willing to walk me through the bare minimum basics of getting this set up to authenticate into our Aurora instance and run a basic GraphQL call? I'm finding the dev docs pretty lacking currently so I'm turning to the expertise of the developer community here hoping someone has already figured this out. Or, if Khoros is reading this, can we have another Developer Webinar where we can walk through this? Or is this something you can offer through training or update the docs with more details? We've reached out to our CSM to see if we can get some 1:1 training but so far it doesn't look like that's an option right now.Solved2.5KViews
Sign in to react to this post13Comments
- MattV1 year agoKhoros Staff
You have 4 authentication options when using Postman to authenticate with the API
- Session Key (local account username and password)
- Bearer token using SDK Key
- Access Token using pre-shared key (Dev Tools API apps)
- OAuth Grant Flow (Community SSO)
Option #1 is the easiest/best option, and what I use most commonly. This means you would login with an account created locally on the community (not using SSO). In the latest version of Aurora (24.08), you can create such as user through Admin > Users > Manage Users.
Setting up Postman
- Create a new collection
- Create a new Environment to use with this collection (to hold variables).
- sessionKey (secret) - leave blank
- hostname (default) - set to your communities hostname (URL without https://)
- username (default) - set to user created in community admin (or your username if local user)
- password (secret) - the users community password
- tapestry (default) - set to t5 (except for some special circumstances)
- sessionStartTime (default) - leave blank
- sessionLastUsed (default) - leave blank
- ht_username (default) - set if you need to login to the community with basic auth credentials (the browser login popup)
- ht_password (secret) - set if you need to login to the community with basic auth credentials (the browser login popup)
- In the collection pre-request script, add the pre-request script (included below)
- Create a new request in your collection
- Set the path to be POST https://{{hostname}}/{{tapestry}}/s/api/2.1/graphql
- Update headers:
Key: li-api-session-key
Value: {{sessionKey}}
- In the request body, add your GraphQL
- Execute Query
- Save your Query (and collection)
Collection Pre-Request Script
var sessionKey = pm.environment.get("sessionKey"); var hostname = pm.environment.get("hostname"); var tapesty = pm.environment.get("tapestry"); var ht_username = pm.environment.get("ht_username"); var ht_password = pm.environment.get("ht_password") var username = pm.environment.get("username"); var password = pm.environment.get("password"); var sessionStartTime = pm.environment.get("sessionStartTime",""); var sessionLastUsed = pm.environment.get("sessionLastUsed",""); const thirtyMinsAgo = Date.now() - (1000 * 60 * 30); const twoHoursAgo = Date.now() - (1000 * 60 * 60 * 2); if (sessionLastUsed == "" || sessionStartTime == "" || sessionLastUsed < thirtyMinsAgo || sessionStartTime < twoHoursAgo || sessionKey == "") { console.log("authenticating"); authenticate(); } else { pm.environment.set("sessionLastUsed", Date.now()); } function authenticate(){ const request = { url: `https://${hostname}/${tapesty}/s/restapi/vc/authentication/sessions/login?user.login=${username}&user.password=${password}&restapi.response_format=json`, method: 'POST', header: { 'Authorization': 'Basic '+btoa(`${ht_username}:${ht_password}`) }, }; pm.sendRequest(request, function (err, response) { if (err) { console.error(err); pm.execution.skipRequest(); return; } const data = response.json(); if (typeof (data.response.error) !== 'undefined' && typeof (data.response.error.message) !== 'undefined') { console.error(data.response.error.message); pm.execution.skipRequest(); throw new Error("Authentication failed (see console)"); } else { console.log("key", data.response.value.$) pm.environment.set("sessionKey", data.response.value.$); pm.environment.set("sessionStartTime", Date.now()); pm.environment.set("sessionLastUsed", Date.now()); } }); }Optional Post-Response script
if (pm.response.code == 401){ console.warn("Got unauthenticated response. Clearing variables."); pm.environment.set("sessionKey",""); pm.environment.set("sessionLastUsed",""); pm.environment.set("sessionStartTime",""); }Sign in to react to this post
liqlAdmin in khoros aurora graphql API
Hi Folks, I want to add roles to the users using graphQL API given below. const ADD_USER_ROLE_MUTATION = gql` mutation addUsersToRole($roleKey: RoleKeyInput!, $users: [UserIdInput!]!) { addUsersToRole(roleKey: $roleKey, users: $users) { result { id name } } } `; const [addUserRole] = useMutation(ADD_USER_ROLE_MUTATION); addUserRole({ variables: { roleKey: { roleName: "role" }, users: [{ id: userId }] } }); The issue I am facing is that when this mutation is executed by an Admin user, the role is successfully added to the target user. However, when the same mutation is executed by a normal user, it fails to add the role due to permission denied errors. Is there a parameter or keyword that can be used in this mutation to allow a normal user to update their own roles or self-related data? For example, in Khoros Classic, we can use the liqlAdmin keyword in REST API requests to bypass such permissions. Is there an equivalent for GraphQL in Khoros Aurora? Thanks in Advance.Solved2.5KViews
Sign in to react to this post13Comments
- saikumarn1 year agoAdvisor
yogeshdixitChange the package name to "@customer/catfact-endpoint". If it still doesn’t work then request the Khoros support team to restart the community.
Sign in to react to this post
API for board information per time period
We are trying to pull some data about specific boards through the API, and we also want to be able to specify a time period. Is there a way to do the following? Total Posts by Board per defined time period Total Members accessing the Board per defined time period Top Solution Authors by Board per defined time period I did find info here Get message counts (khoros.com) that works to get total threads for a board, but I can't figure out how to put time constraints on that. I also found info here Get top-kudoed authors (khoros.com) but I want top solution authors instead of kudoed. Is there a way to do that? ThanksSolved2.3KViews
Sign in to react to this post2Comments
- SuzieH5 years agoKhoros Alumni (Retired)
Hi Akenefick
You might have better luck if you use the Community API v2 /search endpoint with a LiQL query that includes a date range in the WHERE clause. I'm not an engineer, but I was able to get what I think are correct responses on my QA site.
For Total Posts by Board per defined time period, I tried the following query to the messages collection. Note that I included "(depth=0)" in the WHERE clause. That filters results to topics only. Remove it if you want both topics and replies in the response. Also, be sure to look at the note about using date ranges in LiQL queries when using the post_time field as a constraint.
select count(*) from messages where board.id = 'suzieForum1' AND depth=0 AND post_time > 2018-10-07T10:04:30-08:00 AND post_time < 2021-07-19T10:04:30-08:00For Top Solution Authors by Board per defined time period, I tried the following. I took "Top" to be 'most kudoed' so that is how I ordered the results. Also, I only returned messages that had 1 or more kudos with "kudos.sum(weight) > 0". I think you'd want to do something like that so that your response is lighter?
select author, subject, view_href, kudos.sum(weight) from messages where board.id = 'suzieForum1' AND kudos.sum(weight) > 0 AND is_solution = true AND post_time > 2013-10-07T10:04:30-08:00 AND post_time < 2021-07-19T10:18:30-08:00 order by kudos.sum(weight) DESC LIMIT 5I'm not sure how to get Total Members accessing the Board per defined time period. The boards collection has a views field, but I don't think that's unique views, and I don't know of a way to return whether views are by actual community members vs anonymous users. Perhaps someone in Services or Support has done something like this ChadB AdamN TysonN MattV ? Or maybe some of our other Titans Claudius jeffshurtliff allensmith81 ? Hopefully one of these folks can also verify whether my example queries are performant or not 😀.
Cheers!
Sign in to react to this post
Any cons of NOT using LITHIUM.jQuery when calling an endpoint from a component?
Hi folks, I was wondering if using LITHIUM.jQuery when calling endpoints is the only preferred way of doing it: <@liaAddScript> ;(function ($) { $(document).ready(function () { function callLithiumEndpoint() { $.ajax({ url: '${endpointUrl}', }) } callLithiumEndpoint(); }); })(LITHIUM.jQuery); </@liaAddScript> Can it be done with vanilla JavaScript inside a <script> tag as well, for example using fetch? I noticed that endpoints can be triggered from a browser or a postman via their path https://<community-name>/pjakv59666/plugins/custom/<some-path-to-endpoint>/<component-name> Can it be treated as a simple url, passing there parameters and parsing it?Solved2.1KViews
Sign in to react to this post2Comments
- MattV5 years agoKhoros Staff
There are no specific issues with using vanilla javascript to call endpoints.
Using LITHIUM.jQuery is recommended if you intended to use jQuery.
Also, using liaAddScript is recommended if you need the code to be executed near the bottom of the page after OOB javascript has executed (It may also do some minification/obfuscation).
If none of those situations apply or are of concern, feel free to use plain JS in <script> tags. I would just encourage you to be mindful of code organization so the JS makes sense where it is placed, isn't repeated by multiple component includes, etc....
Sign in to react to this post
Logging a user out not working
Hello, I'm currently developing a solution to log out a user from the community sessions automatically. I followed the API Reference here: https://developer.khoros.com/khoroscommunitydevdocs/reference/authsignout I am currently getting the correct response of the user being signed out of all sessions but when I go to the community forums with my test user I can still see the user logged in. This is the json response that I am receiving: { "status":"success", "message":"", "data": { "signed_off_all_sessions":true, "id":"#######" } } Context: we do use a cookie for our users to log into the community site if they are logged into our site. But I have made sure to just be logged into the community site without said cookie when trying this call out. Any help would be welcomed.1.9KViews
Sign in to react to this post12Comments
Aurora Email Templates
Hi everyone, I am new to GraphQL, so please forgive any silly questions here. I've successfully set myself up in Postman, and can retrieve email templates. I understand the documentation here about the process of updating a template, but I am hung up on viewing the HTML within each template so that I might edit that. My end goal, hopefully, is to be able to glean the variable for a post title within say, the Mentions template, and put that into the Subject of the email. So instead of "{User} mentioned you on {Community Title}" I would ideally have a subject that says "{User} mentioned you in the thread {Post Title}" I would also like to edit other pieces of other emails, but looking to cut my teeth on this one. Has anyone had success making a change like this on Aurora, and might be able to point me in the right direction? Thank you!1.8KViews
Sign in to react to this post5Comments
List of all blog articles across the Community, but excepting one or more categories
I'd like to create a custom page that lists all blog articles across the site, but excepts one or more categories. Display parameters (e.g., ORDER BY) are less important than excepting the archives. Has anyone done this? It would be a boost for SEO, as well as a list per se.Solved1.7KViews
Sign in to react to this post22Comments
- luk7 years agoBoss
when I put the JS into a component and save it, it executes from inside Studio, and I had to blow away the component entirely, lest it hang up Studio
this you can easily avoid by wrapping your JS into an #if block, like so:
<#if !page.name?matches('BizAppsPage')> <#-- add your JS, but not in the backend --> <@liaAddScript> </@liaAddScript> <#-- or simply --> <script> // here goes your JS </script> </#if>Regarding the API call I can't really help right now, Lithium/Khoros just locked everybody out of the Dev-Docs Portal (they did a redesign there...), e.g. looks like this when trying to access the API v2 message collection...
Sign in to react to this post
How to determine if a given node is visible to the public?
Hello! I am trying to figure out if it's possible, via API, to determine if a given node is visible to the public. E.g. is the "read posts" permission granted by default on that node. (which I suppose isn't a FULL check of the whole permissions tree but probably adequate for our needs) I've found that the roles collection will give you the list of roles for the node (https://developer.khoros.com/khoroscommunitydevdocs/docs/role-api-support#roles-collection-constraint-combinations ) - but that isn't actually helpful for figuring out what the permissions are, especially the DEFAULT permissions. I've also found the coreNode.permissions.hasPermission (https://developer.khoros.com/khoroscommunitydevdocs/reference/permissionshaspermissionpermission_identifier) call - but I think this can only be used to check if the user in context has a specific permission, not whether or not a node has a certain default permission. (I'm not actually a developer / won't be the one developing this, just trying to determine if a specific enhancement request is possible :-)) Thanks!!Solved1.7KViews
Sign in to react to this post6Comments
coreNode.permissions.hasPermission context object probably is the closest you can get. But it's rather limited as you can only check for the current user AND current node. E.g. you cannot use it easily in a navigation component to show/hide elements without reading permissions.
I'm wondering what you are trying to build though that wouldn't work with Khoros built-in permissioning? The API is quite good at hiding stuff where the current user doesn't have read permissions. Isn't that sufficient for your use case?
Sign in to react to this post