APIを使用してトピックからすべての投稿を取得する

:notebook_with_decorative_cover: これは、Discourse API を使用してトピックからすべての投稿を取得する方法を説明するハウツーガイドです。

Discourse API の多くのルートで返される結果はページネーションされています。

たとえば、“Get A Single Topic” の API エンドポイント - 例: https://examplesite/t/{id}.json は、トピックに 20 件以上の投稿が含まれている場合でも、デフォルトでは 20 件の投稿しか返しません。

この動作のため、Discourse API を使用して .../t/{id}.json エンドポイントを使用してトピックのすべての投稿を取得するには、2 つの方法があります。

クエリパラメータを追加する

トピックからすべての投稿を取得する最も簡単な方法は、リクエスト先の URL に print=true クエリパラメータを追加することです。

例: https://examplesite/t/{id}.json?print=true

print=true クエリパラメータを追加すると、Discourse は返される投稿数 (chunk_size) を 1000 に設定します。これは、トピックに 1000 件を超える投稿がないことを確信している限り、良いアプローチです。

複数の API リクエスト

すべての投稿を取得するもう 1 つの方法は、トピックからすべての投稿を取得するために複数の API リクエストを行うことです。

  1. まず、.../t/{id}.json エンドポイントに最初の GET リクエストを行います。これには、posts 配列と stream 配列を含む posts_stream ハッシュが含まれます。posts 配列は最初の 20 件の投稿を提供します。

  2. 次に、トピック内のすべての投稿 ID を提供する stream 配列をループ処理する必要があります。stream から最初の 20 件の投稿 ID を削除します (そうしないと、理由もなく再ダウンロードすることになります)。

  3. 次に、“Get Specific Posts From a Topic” .../t/{id}/posts.json エンドポイントに、post_ids[] を追加し、stream 配列からすべての ID を 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 には、max prints per hour per user というサイト設定で制御される、1 時間あたりの print=true リクエスト数に制限があります。この設定のデフォルトは、ユーザーが 1 時間あたり 5 件のトピックしか印刷できないようになっています。この設定を 0 に設定すると、レート制限が無効になります。

リクエストに All Users API キーを使用し、リクエストの Api-Username パラメータにサイト管理者のユーザー名を指定した場合、レート制限は適用されないことに注意してください。これは、max prints per hour per user サイト設定を無効にする代わりに、管理者ユーザー名 (例: system) をリクエストに使用できることを意味します。

print=true を含まない API リクエストでレート制限エラーが発生している場合は、レート制限を超えないように API スクリプトにタイムアウトを追加することをお勧めします。または、429 (リクエストが多すぎます) エラーコードをリッスンし、その応答を受け取ったときにリクエストをバックオフすることもできます。

参考までに、標準およびビジネスホストプランに適用されるデフォルトのレート制限は次のとおりです。

discourse/config/discourse_defaults.conf at main · discourse/discourse · GitHub

:grey_exclamation: セルフホストのみ - Discourse API レート制限の調整に関する詳細は、Available settings for global rate limits and throttling を参照してください。

「いいね!」 11

?page クエリパラメータはサポートされていますか? 動作はしますが、予期しない方法です。?page=1 はトピックの最初の投稿しか返さないため、パラメータでページネーションするには https://example.com/t/slug/topicId.json から開始し、https://example.com/t/slug/topicId.json?page=2 にスキップし、最終的に 404 レスポンスが得られるまで続行する必要があります。

サイモン様

?page=1 パラメータを Get a single topic endpoint と共に使用すると、トピックから最初の 20 件の投稿が返され、それ以降のページ番号ごとに最大 20 件の投稿が返されます。

投稿がこれ以上ない場合(例:ページ番号が高すぎて無効な場合)、404 レスポンスが返されます。

ページ番号を指定しない場合、コードはページ番号を 1 に設定するため、?page=1 はトピックリクエストに明示的なページを追加しないのと同じです。

この方法を使用してトピックからすべての投稿を取得したい場合、Discourse API Docs に記載されていなくても、それが可能であるはずです。

「いいね!」 3

ありがとうございます!投稿を取得するMatrixボットを開発中です!

これは間違っていると思います。0に設定すると、印刷が完全に無効になります。この設定の最新の説明は、「/print ページの最大表示回数(印刷を無効にするには0に設定)」です。