Change last_read_post_number for user via API

api

(Joshua Rosenfeld) #1

Background: My company runs an internal Discourse Forum, as well as an internal WordPress site. The forums are configured to use SSO from the WordPress instance. On the forums, there is a category called “Updates”. On the WordPress side, when a user logs in there is the following PHP function:

$results = $this->_getRequest("c/updates.json", null, $username);

The $results are then parsed. For each topic, if the last_read_post_number < highest_post_number then we assume the user hasn’t fully read the topic and display an excerpt of the topic in a div on the WordPress site. In the div, there is an X. The intention is that clicking the X will set the user’s last_read_post_number equal to the highest_post_number so it is “read” in the forums too.

This was initially set up over a year ago by adding a custom controller and route to make the last_read_post_number. Problem is the route was set in a way that overwrote the Discourse routes.rb file, causing intermittent and eventually permanent problems.


Is there a way to do this via a simple API call (or calls)?


Adding a ruby controller via plugin
(Sam Saffron) #2

You could simulate this by using post_timings, look at the ajax calls made why you read a topic.

POST
https://meta.discourse.org/topics/timings

Form Data
timings[1]:14000
topic_time:19999
topic_id:60454

So you would make a API call on behalf of the user using the API to simulate that they read it.


(Joshua Rosenfeld) #3

Thanks @sam.

This is my first time digging this deep into the code, so I’m afraid I’m getting lost. I’ve found post_timing.rb - but not understanding what exactly each function does, plus my limited knowledge of ruby - I’m not sure where to go from here.

I’m also unclear what your code snippet is showing - what exactly is timings and topic_time. Would you be able to point me more specifically to where the ajax calls are made when reading a topic?


Edit: I found update_last_read in topic_user.rb. Is that something that can be called from the API? Does it accomplish what I’m looking for?


(Rafael dos Santos Silva) #4

When you scroll trough a topic, Discourse sends info about the point you are reading to the server in the format:

curl -X POST 'https://meta.discourse.org/topics/timings' --data 'timings%5B1%5D=20000&timings%5B2%5D=20000&timings%5B3%5D=19000&topic_time=20000&topic_id=60454'

(Using this topic as an example).

You should send the same request from your main app to simulate “reading” a topic.


(Joshua Rosenfeld) #5

Thanks @Falco, I think I’m starting to wrap my head around this.

The timings array: timings[x] - is x the post number? And what is the value being stored in the array? Milliseconds?


(Rafael dos Santos Silva) #6

Yes, the relative post number.

I believe that is the time in milliseconds spent reading that post.


(Joshua Rosenfeld) #7

OK. Looking at the API Docs - I’m assuming I’d use api_username=bob if I wanted to update bob’s post timings?

So the entire request would be the following if I wanted to mark the first post of topic 1234 as read by user bob for 20 seconds, correct?

curl -X POST 'https://{my_domain}/topics/timings?api_key={api_key}&api_username=bob' --data 'timings[1]=20000&topic_time=20000&topic_id=1234'