How to use API key in AJAX call?

I am trying to programmatically get back information about a group from the discourse API. I have the code for this in my customize dashboard, under < /head>. I am the admin of my forum.

It’s not working, and I think it may be because I don’t understand how the API keys work.

If I want Discourse to make a call to the API to get back information about a group, every time any user visits a certain page, what’s the right API key setup?

This is what I have so far:

In my dashboard, I have gone to API -> New API Key. There, I need to select “User Level”. Sorry for the basic question, but what does “User Level” mean here? (the API call needs to run any time any user goes to the given page).

I’ve selected “All Users”. I then generate the token.

Then, in my customize css/html dashboard under < /head> I have entered the following in between relevant <script> tag:

var groupName = [RELEVANT GROUP NAME]
var token = [TOKEN I GENERATED]
$.ajax({
     url: 'https://myforum.com/groups/groupName.json',
      contentType: "application/json",
      headers: {
          "Api-Key": token,
          "Api-Username": "system"
        },
        dataType: 'json',
        success: function(result){
             console.log('result = ' + result);
         }
})

The code runs, but returns an error saying not authorized (even though I am the admin, and a member of the group I’m using to experiment).

What do I need to change?

1 Like

Isn’t this going to expose your All Users API Key to everyone who can view your site? I think you’ll need to find another approach for getting the group data from a theme component.

4 Likes

If the group info that you need isn’t in the json load available to the user then you need to figure out how add it to the serializer. Searching for “add to serializer” or maybe addToSerializer or add_to_serializer in existing theme components and plugins might help.

But shouldn’t the code work in any event? The API provides the ability to get back information about a group. I still remain confused as to how this is supposed to work I guess.

What would be the normal way of using the API to get information about a specific group?

The key piece of info that I want is whether the user is a group owner or not of the group. This information is returned by the Json API. So when a user goes to a particular page, I want to send a call to the API to get back information about a group, which in the basic response includes whether the user logged into the client is an owner.

This seems like a straight forward implementation of the API. It seems, however, that this operation requires an API key, but the method that I’ve used so far is not working.

I don’t think that creating a separate plug-in or theme component is required here, as this operation is one of the basic ones the Json API provides.

Curious if there is a way to use the API with a key that wouldn’t expose the key (ie, what would be the standard/best practice way to use the API).

EDIT: If for some reason this is not appropriate for the API call, then yes it would have to get serialized. Does anyone have working code for that? I understand that there is an add_to_serializer method, but I haven’t gotten the syntax to quite work, and have struggled to find working examples of method.

Dear @JQ331

Yes, I did a quick check for you (as a reference) and logged into a test forum as a staff member and pulled the staff group, and got the expected results:

JSON object for staff group by staff member
{
  "group": {
    "id": 3,
    "automatic": true,
    "name": "staff",
    "display_name": "staff",
    "user_count": 1,
    "mentionable_level": 0,
    "messageable_level": 0,
    "visibility_level": 1,
    "automatic_membership_email_domains": null,
    "primary_group": false,
    "title": null,
    "grant_trust_level": null,
    "incoming_email": null,
    "has_messages": false,
    "flair_url": null,
    "flair_bg_color": null,
    "flair_color": null,
    "bio_raw": null,
    "bio_cooked": null,
    "bio_excerpt": null,
    "public_admission": false,
    "public_exit": false,
    "allow_membership_requests": false,
    "full_name": null,
    "default_notification_level": 3,
    "membership_request_template": null,
    "is_group_user": true,
    "is_group_owner": true,
    "members_visibility_level": 0,
    "can_see_members": true,
    "publish_read_state": false,
    "is_group_owner_display": false,
    "mentionable": false,
    "messageable": false
  },
  "extras": {
    "visible_group_names": [
      "admins",
      "moderators",
      "staff",
      "trust_level_0",
      "trust_level_1",
      "trust_level_2",
      "trust_level_3",
      "trust_level_4"
    ]
  }
}

… and I also tried doing the same logged out, and got the expected result:

{"errors":["You are not permitted to view the requested resource."],"error_type":"invalid_access"}

So, this means, or so it seems to me, that all is working as it should.

FYI @JQ331, I did not need an API key for this action as a logged in user (from the browser).

    "is_group_owner": true,
5 Likes

@neounix: Thanks very much for your reply. It stopped my wild goose chase. I was thinking the reason I was getting the unauthorized response was because of an authentication issue.

Turns out, you’re right, there’s no API key required for this action. Rather, it was a (simple) code error, which is clear from the code I posted above, but that I had missed before (I was incorrectly putting in the variable for the AJAX url).

Here’s the working code:

var groupName = [RELEVANT GROUP NAME]
var token = [TOKEN I GENERATED]
$.ajax({
     url: 'https://myforum.com/groups/' + groupName + '.json',    //this is where the old error was
      contentType: "application/json",
        dataType: 'json',
        success: function(result){
             console.log('full response = ' + JSON.stringify(result));
             console.log('is group owner = ' + result.group.is_group_owner);  //note this will either be true or null           
     }
})

I was getting the unauthorized response before, because the prior URL I was entering had the incorrect group name (it was being read as “groupName”).

2 Likes