Discourse REST API の包括的な例

いくつかのガイドで、さまざまな API の使用方法や説明が紹介されています。

このガイドでは、API の使い方を示す実践的かつ包括的な例を掲載しています。

:warning: このガイドのすべてのコード例は、ベストプラクティスを示すものではなく、そのまま使用することを意図していません。
API の使用方法に焦点を当てるため、多くの検証やエラーハンドリングなどは意図的に省略またはスキップされています。

API は何に使用されますか?

Discourse でのほとんどの操作(投稿、いいね、設定の編集など)は、エンドポイント[1] へのリクエストを送信することで API を使用して行われます。

例えば、meta でトピックを作成すると、https://meta.discourse.org/posts.json に対して POST リクエストが送信されます。このリクエストには、投稿者、タイトル、カテゴリ、タグ、投稿内容などが含まれます。

API をカスタムに使用するのは、通常、自動化されたタスクを達成するためであり、Web フック、スクリプト、サードパーティ製ソフトウェアや API などの他のサービスと組み合わせて行われることが多いです。

API を使用するには、API 認証情報が必須です。これは数回のクリックで設定でき、以下のガイドに従ってください: Create and configure an API key

これ以上待たずに、API の使用例を最初のステップから見ていきましょう。:technologist:

月次トピックの作成

この例では、curlcron を使用して、フォーラムに月次で「フリートーク」トピックを作成します。オンラインコミュニティでよく行われている慣習です :slight_smile:

API キーの作成

API キー作成ガイドに従ってください。User Level を「Single User」に設定します。
選択したユーザーが月次トピックの著者になります。
その後、Global スコープまたは Granular スコープを選択できます。Granular を選択する場合は、少なくとも Topicswrite アクセス権が必要です。
生成された API キーをメモしてください。:writing_hand:

curl コマンドの作成

サーバーのコマンドラインから、以下のコマンドを実行して、curl と Discourse の REST API を使用して API キーでトピックが正常に作成されるか確認します。

curl -X POST "https://your-discourse.com/posts.json" -H "Content-Type: application/json" -H "Api-Key: YOUR_API_KEY" -H "Api-Username: YOUR_USERNAME" -d "{\"title\": \"Test topic creation with the API\", \"raw\": \"And here's the topic's content\", \"category\": CATEGORY_ID }"

以下の部分を置き換えてください:

  • your-discourse.com をフォーラムのドメインに置き換える
  • YOUR_API_KEY を API キーに置き換える
  • YOUR_USERNAME を API キーで選択したユーザー名に置き換える
  • CATEGORY_ID をトピックを投稿したいカテゴリの ID に置き換える

すべてが正しく設定されていれば、新しいテストトピックがフォーラムに作成されます。例:

この時点で、作業の大部分は完了しています!次に、トピックのタイトルと内容をより適切なものに変更し、トピック作成の繰り返しを設定します。

まず、トピックのタイトルを以下のように変更します:
Test topic creation with the API
から:
Free talk of the month - $(date +\%B)
へ。

同様に、内容も以下のように変更します:
Test topic creation with the API
から:
What have you appreciated the most and the less during $(date +\%B -d 'last month')?\nFeel free to share your feelings and provide ideas. 🙂
へ。

:information_source: ここでは、タイトルに現在の月の名前を、内容には先月の名前を挿入するために、date という Unix コマンドを使用しています。

:information_source: 内容内の \n は改行を作成します。

コマンドラインを使用して更新された curl リクエストを実行できます。これで、フォーラムに以下のような新しいトピックが作成されているはずです:

繰り返しイベントの設定

毎月 1 日に curl コマンドを実行する cron タスクを作成します。:calendar:

以下のコマンドで cron ファイルを編集します:

crontab -e

ファイルの末尾に以下の行を挿入し(リクエストの内容を必要に応じて置き換えて)、変更を保存します。

0 0 1 * * curl -X POST "https://your-discourse.com/posts.json" -H "Content-Type: application/json" -H "Api-Key: YOUR_API_KEY" -H "Api-Username: YOUR_USERNAME" -d "{\"title\": \"Free talk of the month - $(date +\%B)\", \"raw\": \"What have you appreciated the most and the less during $(date +\%B -d 'last month')?\nFeel free to share your feelings and provide ideas. 🙂\", \"category\": 4 }"

:information_source: 0 0 1 * * の部分は、コマンドが実行される間隔を定義します。構文の詳細については、こちらをご覧ください: https://crontab.guru

完了です!これで、サーバーは Discourse の REST API、curl リクエスト、および cron タスクを使用して、毎月 1 日に新しい「フリートーク」トピックを作成します。:partying_face:

テーマの色テーマを自動的に変更する

デフォルトのテーマを現在の季節に合わせた色テーマに変更してみましょう :snowflake: :hibiscus: :sunny: :fallen_leaf:

Ruby を使用して月のチェックを行い、cron タスクでスクリプトを実行します。

Ruby と cron 以外にも多くの方法がありますが、このガイドはさまざまなツールで API を使用する方法を示すことも目的としています。

テーマと色テーマの準備

色テーマを変更したいテーマを選択し、その ID を取得します。ID はテーマの URL に含まれています。例えば、このテーマの ID は 1 です:

4 つの色パレットを作成し、それぞれの ID もメモしてください。
ここでは、秋のパレットの ID は 17 です:

スクリプトの作成

サーバーに Ruby をインストール します。

seasons.rb ファイルを作成します。この例では、~/scripts/ 内に置くと仮定します。

以下の内容をこのファイルに記述します。テーマのエンドポイントに対して PUT リクエストを送信し、色テーマ ID を含むペイロードを送信します。

require 'net/http'
require 'json'
require 'date'

current_month = Date.today.month
color_scheme_id = case current_month
                  when 1..3 then 18 # Winter
                  when 4..6 then 15 # Spring
                  when 7..9 then 16 # Summer
                  else           17 # Autumn
                  end

uri = URI('https://your-discourse.com/admin/themes/THEME_ID.json')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Put.new(uri, {
  'Api-Key' => 'YOUR_API_KEY',
  'Api-Username' => 'YOUR_USERNAME',
  'Content-Type' => 'application/json'
})

request.body = JSON.generate({
  "theme" => {
    "color_scheme_id" => color_scheme_id
  }
})

response = http.request(request)

以下の部分を置き換えてください:

  • your-discourse.com をフォーラムのドメインに置き換える
  • YOUR_API_KEY を API キーに置き換える
  • YOUR_USERNAME を API キーで選択したユーザー名に置き換える
  • THEME_ID をテーマの ID に置き換える。テーマの設定ページの URL の末尾にあります。
    例えば、https://your-discourse.com/admin/customize/themes/38 の場合、テーマの ID は 38 です。

スクリプトを手動で試してみましょう。
まず、Discourse のインターフェースで、季節固有の色テーマでない場合に、それを設定します。

その後、以下のコマンドでスクリプトを実行します:

ruby ~/scripts/seasons.rb

ブラウザをリフレッシュしてください。テーマで使用されている色テーマが変更されているはずです。:slight_smile:

最後の作業は、季節が変わるたびに毎月 1 日にこのスクリプトを実行する cron ジョブを作成することです。

cron タスクの作成方法を忘れた場合は、最初の例 をご覧ください。

0 0 1 1,4,7,10 * ruby ~/scripts/seasons.rb

完了です!これで、フォーラムは新しい季節の始まりごとに新しい色に変わります!:sunny: :partying_face:

Web サーバーで Web リクエストを受け取り、そのデータを使用して Discourse のトピックを更新する

これは少し複雑です!:technologist:

ツールには PHP を使用します。つまり、どこかで PHP がインストールされた動作する Web サーバーを持っていると仮定します。

この例では、Ko-Fi(寄付サービス)の Web フックペイロードを PHP ページで受け取り、受け取ったデータを使用して Discourse の API でトピックのタイトルと内容を更新します。

具体的には、寄付額と日付でトピックのタイトルを更新し、過去の寄付一覧を表に新しい行を追加します(トピックを自動的にバンプします :shushing_face:):

ユーザーが寄付を行うたびに、Ko-Fi[2] が PHP スクリプトにリクエストを送信します。

Ko-Fi の設定

Ko-Fi の Web フックページ で設定を行いました。PHP ファイルの URL を追加し、詳細セクションに隠されている検証トークンをメモしました。

単一の寄付に対して、Ko-Fi は以下のようなペイロードを PHP スクリプトに送信します:

data = {
  "verification_token": "d8546b84-c698-4df5-9811-39d35813e2ff",
  "message_id": "a499df4c-7bbb-4061-b4a6-8b9d969da689",
  "timestamp": "2023-10-19T13:35:06Z",
  "type": "Donation",
  "is_public": true,
  "from_name": "Jo Example",
  "message": "Good luck with the integration!",
  "amount": "3.00",
  "url": "https://ko-fi.com/Home/CoffeeShop?txid=00000000-1111-2222-3333-444444444444",
  "email": "jo.example@example.com",
  "currency": "USD",
  "is_subscription_payment": false,
  "is_first_subscription_payment": false,
  "kofi_transaction_id": "00000000-1111-2222-3333-444444444444",
  "shop_items": null,
  "tier_name": null,
  "shipping": null
}

このペイロードを受け取り、必要な 2 つの情報を抽出します:

  • amount (3.00) を整数に丸めます。

  • timestamp (2023-10-19T13:35:06Z) をより見やすい日付形式に変換します。

Ko-Fi のペイロードの受け取り

まず、以下のコードを PHP ページに記述して、Ko-Fi からのリクエストを受け取ります。POST リクエストを受け取ったことと、トークン値が Ko-Fi の Web フックページで指定されたものと一致することを確認します。また、前述のように金額と日付をフォーマットします。

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $jsonData = json_decode($_POST['data'], true);

    if ($jsonData['verification_token'] === 'YOUR_VERIFICATION_TOKEN') {
        $amount = floor(floatval($jsonData['amount']));
        $date = (new DateTime($jsonData['timestamp']))->format('d/m/Y');
    }
}

以下の部分を置き換えてください:

  • YOUR_VERIFICATION_TOKEN を Ko-Fi から提供されたトークンに置き換える

トピックのタイトルの更新

次のステップは、トピックのタイトルを更新することです。PHP スクリプト内で curl を使用して、適切なエンドポイントに PUT リクエストを送信します。

        $putData = json_encode(['title' => '🥳 New donation: ' . $amount . '€ on ' . $date]);
        $ch = curl_init('https://your-discourse.com/t/test-new-topic/TOPIC_ID');
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($ch, CURLOPT_POSTFIELDS, $putData);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($putData),
            'Api-Key: YOUR_API_KEY',
            'Api-Username: YOUR_USERNAME'
        ]);
        curl_exec($ch);

以下の部分を置き換えてください:

  • your-discourse.com をフォーラムのドメインに置き換える
  • TOPIC_ID を正しいトピックの ID に置き換える
  • YOUR_API_KEY を API キーに置き換える
  • YOUR_USERNAME を API キーで選択したユーザー名に置き換える

投稿の内容の更新

トピックの最初の投稿に新しい内容を追加するには、まず GET リクエストで現在のコンテンツを取得する必要があります。

        $ch_get = curl_init('https://your-discourse.com/posts/POST_ID.json');
        curl_setopt($ch_get, CURLOPT_RETURNTRANSFER, true);
        $currentContent = json_decode(curl_exec($ch_get), true)['raw'];

以下の部分を置き換えてください:

  • POST_ID を正しい投稿の ID に置き換える[3]

最後に、金額と日付を表に新しい行を追加して投稿内容を更新します。PUT リクエストを使用してこれを行います。

        $updatedContent = $currentContent . "\n| " . $amount . "€ | " . $date . " |";
        $putPostData = json_encode(['post' => ['raw' => $updatedContent]]);
        $ch_put = curl_init('https://your-discourse.com/posts/POST_ID');
        curl_setopt($ch_put, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($ch_put, CURLOPT_POSTFIELDS, $putPostData);
        curl_setopt($ch_put, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($putPostData),
            'Api-Key: YOUR_API_KEY',
            'Api-Username: YOUR_USERNAME'
        ]);
        curl_exec($ch_put);

以下の部分を置き換えてください:

  • your-discourse.com をフォーラムのドメインに置き換える
  • POST_ID を正しい投稿の ID に置き換える
  • YOUR_API_KEY を API キーに置き換える
  • YOUR_USERNAME を API キーで選択したユーザー名に置き換える

最終的なコードは以下のようになります:

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $jsonData = json_decode($_POST['data'], true);

    if ($jsonData['verification_token'] === 'YOUR_VERIFICATION_TOKEN') {
        $amount = floor(floatval($jsonData['amount']));
        $date = (new DateTime($jsonData['timestamp']))->format('d/m/Y');

        $putData = json_encode(['title' => '🥳 New donation: ' . $amount . '€ on ' . $date]);
        $ch = curl_init('https://your-discourse.com/t/test-new-topic/TOPIC_ID');
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($ch, CURLOPT_POSTFIELDS, $putData);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($putData),
            'Api-Key: YOUR_API_KEY',
            'Api-Username: YOUR_USERNAME'
        ]);
        curl_exec($ch);

        $ch_get = curl_init('https://your-discourse.com/posts/POST_ID.json');
        curl_setopt($ch_get, CURLOPT_RETURNTRANSFER, true);
        $currentContent = json_decode(curl_exec($ch_get), true)['raw'];

        $updatedContent = $currentContent . "\n| " . $amount . "€ | " . $date . " |";
        $putPostData = json_encode(['post' => ['raw' => $updatedContent]]);
        $ch_put = curl_init('https://your-discourse.com/posts/POST_ID');
        curl_setopt($ch_put, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($ch_put, CURLOPT_POSTFIELDS, $putPostData);
        curl_setopt($ch_put, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($putPostData),
            'Api-Key: YOUR_API_KEY',
            'Api-Username: YOUR_USERNAME'
        ]);
        curl_exec($ch_put);

        curl_close($ch);
        curl_close($ch_get);
        curl_close($ch_put);
    } else {
        http_response_code(403);
        echo "Invalid verification token.";
    }
} else {
    http_response_code(405);
    echo "Only POST requests are allowed.";
}
?>

ガイドの冒頭で警告したことを再度強調します :stuck_out_tongue:

:warning: このガイドのすべてのコード例は、ベストプラクティスを示すものではなく、そのまま使用することを意図していません。
API の使用方法に焦点を当てるため、多くの検証やエラーハンドリングなどは意図的に省略またはスキップされています。

これで、Ko-Fi からテストリクエストをトリガーし、タイトルと内容の両方がどのように更新されるかを確認できます。:slight_smile:

以上です!
Ko-Fi で誰かが寄付を行うたびに、トピックが更新され、バンプされるようになります!:partying_face:


:information_source: このトピックはウィキです。エラーを見つけた場合は修正し、このガイドを改善する方法について議論することを歓迎します。


  1. この文脈では特定の URL を指します。例えば、https://your-discourse.com/posts.json のようなものです。 ↩︎

  2. API に関するちょっとした情報: https://help.ko-fi.com/hc/en-us/articles/360004162298-Does-Ko-fi-Have-an-API-or-Webhook- ↩︎

  3. 投稿 ID は HTML コード内で確認できます。data-post-id="POST_ID" という属性を持つ <article> 要素です。 ↩︎

「いいね!」 10

これは素晴らしいですね、@Canapin さん。必要とされていたものだと思います。私も少し前にこのようなものを探していました。ありがとうございます!:slight_smile:

「いいね!」 3

サブトピックを指定するにはどうすればよいですか?
jBASEにAutoDocというサブトピックがある場合、区切り文字(jBASE>AutoDoc)を使用してトピックにまとめるのですか、それともカテゴリタグがありますか?

解決しました。カテゴリまたはサブカテゴリページにいるとき、URLにはカテゴリ名の代わりに#が表示されます。サブカテゴリには独自の番号があるため、何もマッシュアップする必要はありません。

更新された情報で記事を置き換えるにはどうすればよいですか?

現在、成功した更新の代わりに次のエラーが表示されます。
{“action”:“create_post”,“errors”:[“Title has already been used”]}

投稿を更新するための別のアクションはありませんか?

リクエストされたcurlはアクションを指定していません。

curl -X POST “http://LOCATION.local/posts.json” -H “Content-Type:
application/json” -H “Api-Key: APIKEY” -H “Api-Username: BOB” -d "{"title": "PL AUTO.DOC.FUN SCS
-TEST Autodoc","raw": " …

トピックを更新するためにエンドポイントを使用する場合はどうなりますか?

または、投稿を更新する場合はどうなりますか?

それが見えませんでした。よく見つけましたね。試してみます。ありがとうございます。

追記:まだ何か足りないようです。唯一の違いは edit_reason が追加されたことのようです。それを試しましたが、違いはありませんでした。

以下は、完全なcurlコマンドです。

curl -X POST “http://localhost.local/posts.json” -H “Content-Type:
application/json” -H “Api-Key: API KEY” -H “Api-Username: BOB” -d “{"title": "Title of the Article","raw": "The quick brown fox jumped over the lazy dog.2023-12-26.","edit_reason": "auto","category": 66}”

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1927 0 65 100 1862 1177 33729 --:–:-- --:–:-- --:–:-- 34481

{“action”:“create_post”,“errors”:[“Title has already been used”]}

「いいね!」 1

トピックまたは投稿を更新するには、PUT メソッドを使用してください。

Firepup が指摘したように、投稿のコンテンツを更新したい場合は、次の API を使用できます: Discourse API Docs

問題は、PUTにはID#が必要ですが、それらが手元にないことです。
新しいトピックをPOSTすると、#を収集しますが、その番号は機能しないようです。
ブラウザを使用してトピックを表示すると、別の#が表示されますが、その番号は機能しないようです。

例:トピックを生成し、POSTイベントは{“id”:3244,…}を返しました。
それにアクセスするためのURLは…test-pl-auto-doc-fun/2803と言っています。

そのため、このPUTを送信します。
curl -X PUT “http://LOCATION.local/posts.json/3244” -H “Content-Type: application/json” -H “Api-Key: KEY” -H “Api-Username: system” -d
“{"title": "Autodoc SCS-TEST PL AUTO.DOC.FUN","raw": "…","edit_reason": "auto","category": 66}”

そして、Page Not FoundのHTMLが返ってきました。

/posts/3244.json になるはずです。

その POST リクエストから取得する id は、投稿 ID(最初の投稿の ID)であり、すべての投稿で一意です。

ガイド内の両方の動画が404エラーを返しているようです。

「いいね!」 1

APIはAIヘルパーを呼び出すために使用できますか?

そうは思いません。なぜなら、docs.discourse.org には言及されていません。ただし、間違っている可能性もあります。

API経由でAIヘルパーを使用すべき理由は何ですか🤔

ウェブサイトに接続され、7年分の知識が蓄えられたフォーラムに接続して質問に答えるボットを構築すること。

または、7年分の知識が蓄えられたフォーラムに接続して質問に答える、メールに応答できるボットを構築すること。

それなら、おそらく ai-bot の方がお探しのものに近いでしょう。ai-helper は、投稿の読み書きを支援するものです。

注記にあるように、それは完全なリストではありません。

注記: リストにないエンドポイントについては、Discourse API のリバースエンジニアリング ガイドに従って、API エンドポイントの使用方法を調べてください。

「いいね!」 2

UXからできることは何でもAPIから行うことができます。Discourse APIのリバースエンジニアリング

APIでは常に新しいものが追加されたり変更されたりしています。ブラウザで実際に何が起こっているかを見るのが一番簡単だと思います。

「いいね!」 5

素晴らしいアイデアです。ありがとうございます!