Получить все сообщения из темы через 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 лайков

Поддерживается ли параметр запроса ?page? Он работает, но неожиданным образом: ?page=1 возвращает только первый пост в теме. Поэтому для пагинации с использованием этого параметра нужно начать с https://example.com/t/slug/topicId.json, затем перейти к https://example.com/t/slug/topicId.json?page=2 и продолжать, пока в итоге не будет получен ответ 404.

Привет, Саймон,

Использование параметра ?page=1 с конечной точкой получения одного топика вернёт первые 20 сообщений из топика, а каждая последующая страница вернёт до 20 сообщений.

Если сообщений больше нет (например, номер страницы слишком велик и недействителен), вы получите ответ с кодом 404.

Если вы не укажете номер страницы, код автоматически установит его равным 1, поэтому ?page=1 равносильно отсутствию явного указания страницы в запросе к топику.

Если вы захотите использовать этот метод для получения всех сообщений из топика, вы сможете это сделать, хотя в документации API Discourse это не упоминается.

3 лайка

Спасибо! Работаю над ботом для Matrix, чтобы получать посты!

Я думаю, это неверно. Установка в 0 полностью отключит печать. Последнее описание этой настройки: «Максимальное количество показов страницы /print (установите 0, чтобы отключить печать)». discourse/app/controllers/topics_controller.rb at 68e57190df85210f70471c67e532a6ea55b3430b · discourse/discourse · GitHub