Fetch All Posts from a Topic Using the API

:notebook_with_decorative_cover: Это руководство по эксплуатации, объясняющее, как получить все сообщения из темы с помощью API Discourse.

Результаты, возвращаемые API Discourse для многих маршрутов, имеют постраничную разбивку.

Например, конечная точка API для “Получение одной темы” — например, https://examplesite/t/{id}.json — по умолчанию возвращает только 20 сообщений, даже если тема содержит более 20 сообщений.

Из-за этого поведения есть два способа использовать API Discourse для получения всех сообщений темы через конечную точку .../t/{id}.json.

Добавление параметра запроса

Самый простой способ получить все сообщения из темы — добавить параметр запроса print=true к URL-адресу, к которому вы отправляете запрос.

Пример: https://examplesite/t/{id}.json?print=true

При добавлении параметра запроса print=true Discourse устанавливает chunk_size (размер пакета) для количества возвращаемых сообщений на 1000. Это означает, что такой подход хорош, если вы уверены, что в ваших темах не более 1000 сообщений.

Множественные запросы к API

Другой способ получения всех сообщений — выполнить несколько запросов к API для получения всех сообщений из темы:

  1. Сначала выполните начальный запрос GET к конечной точке .../t/{id}.json. Она будет содержать хэш posts_stream, который включает массив posts и массив stream. Массив posts предоставит вам первые 20 сообщений.

  2. Теперь вам нужно перебрать массив stream, который содержит все идентификаторы сообщений в теме. Удалите первые 20 идентификаторов сообщений из потока (иначе вы будете повторно загружать их без необходимости).

  3. Затем вы можете выполнить дополнительные запросы к конечной точке “Получение конкретных сообщений из темы” .../t/{id}/posts.json, добавить параметр post_ids[] и передать все идентификаторы из массива stream пакетами по 20. Пример: .../t/{id}/posts.json?post_ids[]=46&post_ids[]=47&post_ids[]=48&post_ids[]=49&post_ids[]=50&post_ids[]=51&post_ids[]=52&post_ids[]=53&post_ids[]=54&post_ids[]=55&post_ids[]=56&post_ids[]=57&post_ids[]=58&post_ids[]=59&post_ids[]=60&post_ids[]=61&post_ids[]=62&post_ids[]=63&post_ids[]=64&post_ids[]=65

Ограничения скорости

Если при выполнении множественных запросов к API вы получаете сообщение об ошибке Error: you have performed this action many times, please try again later (Ошибка: вы выполнили это действие слишком много раз, пожалуйста, повторите попытку позже), это означает, что вы достигли ограничений скорости для ключа API.

Discourse имеет ограничение на количество запросов с параметром print=true, которые можно выполнить за час. Это контролируется настройкой сайта max prints per hour per user (максимальное количество распечаток в час на пользователя). По умолчанию эта настройка позволяет пользователям распечатывать только 5 тем в час. Установка значения 0 полностью отключит функцию печати (запросы с print=true будут возвращать ошибку 403).

Обратите внимание, что ограничение скорости не применяется, если запрашивающий пользователь является администратором. Это означает, что вы можете использовать ключ API с именем администратора (например, system) для параметра Api-Username запроса, чтобы обойти ограничение скорости печати.

Если вы сталкиваетесь с ошибками ограничения скорости при выполнении запросов к API, которые не содержат print=true, мы рекомендуем добавить тайм-аут в ваш скрипт API, чтобы не превысить лимиты. Альтернативно, вы можете отслеживать коды ошибок 429 (слишком много запросов) и делать паузу в выполнении запросов при получении такого ответа.

Для справки, приведенные ниже ограничения скорости по умолчанию применяются к нашим стандартным и бизнес-планам хостинга:

:grey_exclamation: Только для самостоятельного размещения — См.: Available settings for global rate limits and throttling для получения подробной информации о настройке ограничений скорости API Discourse.

11 лайков

Is the ?page query param supported? It works, but in a surprising way - ?page=1 only returns the first post in the topic, so to paginate with the parameter you need to start with https://example.com/t/slug/topicId.json, then skip to https://example.com/t/slug/topicId.json?page=2, then keep going until you eventually get a 404 response.

Hi Simon,

Using the ?page=1 parameter with the Get a single topic endpoint will return the first 20 posts from a topic, and each subsequent page number will return up to 20 posts.

When there are no most posts available (EX: the page is too high and not valid), you’ll get a 404 response.

If you don’t specify a page number, the code will set a page number of 1, so ?page=1 is the same as not appending an explicit page to the topic request.

If you wanted to use this method to fetch all posts from a topic, you should be able to do so, even though it is not mentioned within the Discourse API Docs.

3 лайка

Thanks! Working on a matrix bot to fetch post!

I think this is wrong. Set to 0 will disable print at all. The latest description for this setting is Maximum number of /print page impressions (set to 0 to disable printing).