Using the Discourse API ruby gem to post a topic as a specific user

I’m trying to use the following to post a new topic as a non-staff user via the Discourse API ruby gem:

$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require File.expand_path('../../lib/discourse_api', __FILE__)

client = DiscourseApi::Client.new("https://www.example.com")
client.api_key = "GLOBAL_KEY"
client.api_username = "ADMIN_USERNAME"

topic = client.create_topic (
  category: "Category",
  skip_validations: true,
  auto_track: false,
  title: "This is a test topic",
  created_at: "Sat Jul 22, 2016 5:00 pm GMT-0700",
  api_username: "NORMAL_USER_USERNAME",
  raw: "This is just a test"
)

When I run the above, I get:

/Users/me/discourse_api/lib/discourse_api/client.rb:147:in `handle_error': {"status"=>404, "error"=>"Not Found"} (DiscourseApi::NotFoundError)
	from /Users/me/discourse_api/lib/discourse_api/client.rb:136:in `request'
	from /Users/me/discourse_api/lib/discourse_api/client.rb:87:in `post'
	from /Users/me/discourse_api/lib/discourse_api/api/topics.rb:12:in `create_topic'
	from test.rb:11:in `<main>'

There are no restrictions on the category. And I can confirm that the normal user is able to post a new topic through the actual site.

Interestingly, if I grant the normal user moderation power, everything works fine - the topic posts. This seems to imply there is a permission issue going on somewhere, but I’m having trouble tracking it down.

It also might be worth noting that I am able to post a reply to an existing topic as the normal user using create_post() without granting them moderation power.

Any suggestions would be greatly appreciated!

Thanks!

4 Likes

I wonder if you can simply use create_post here for creating the topic… @blake any ideas?

4 Likes

Thanks for looking into this! Unfortunately create_post requires topic_id as an argument and I don’t believe you can pass it a title either.

3 Likes

I’m pretty sure this is a Category not found error. If you use the category id instead of the category name does it work?

5 Likes

Unfortunately it’s the same situation. If I run it after I’ve granted the normal user moderation power, it goes through fine, but as a normal user without moderation power, I still get the DiscourseApi::NotFoundError

If you check your /logs does it show something like this?:

If you can find an error message besides just 404 that will be helpful in debugging.

3 Likes

Unfortunately my /logs are clean. Not even a mention of the 404 there. I’m not sure how relevant this is, but just in case, I’m trying to create the new topic on a test production environment.

I haven’t been able to track down any other errors outside of the one I posted that displays in the console when I try to run the ruby file.

Out of curiosity, have you attempted to repro using the scenario I’ve laid out? I may just try a new, clean instance and rule things out one at a time. Maybe there’s some site setting or configuration that’s getting in the way.

I’ve been running it in a development environment, but just tested it in a production env. The logs don’t show for me either, but I’m able to replicate the same behavior is both env’s.

If you create a post as an admin or moderator and you specify the category as a string it does its best to guess the correct category and will work, but a regular user will hit this line

https://github.com/discourse/discourse/blob/master/lib/new_post_manager.rb#L95

causing a 404 if you don’t specify the category as an id.

This works

topic = {
  category: 8,
  skip_validations: true,
  auto_track: false,
  title: random_string,
  api_username: "ifvhonqlmxesadwpktc",
  raw: random_string
}
new_topic = client.create_topic(topic)

This causes a 404:

topic = {
  category: "Category",
  skip_validations: true,
  auto_track: false,
  title: random_string,
  api_username: "ifvhonqlmxesadwpktc",
  raw: random_string
}
new_topic = client.create_topic(topic)
3 Likes

Awesome! I really appreciate you taking the time to look into this.

I will give the category ID a try again when I get home and make sure I have all the arguments in place exactly like your example. When I originally tried with the category ID, I may have have accidentally left something out after trying various things.

It worked! Thank you so much :heart_eyes:

3 Likes