这里有 几份指南,涵盖了各种 API 用途或说明。
本文档提供实用且全面的示例,介绍如何使用 API。
本指南中的所有代码示例并非旨在展示最佳实践,也不建议直接照搬使用。
为了专注于 API 的使用,我们有意忽略或省略了许多检查、错误处理等内容。
API 的用途是什么?
你在 Discourse 中的大多数操作(发帖、点赞、编辑设置等)都是通过向某个端点[1] 发送请求,利用 API 来完成的。
例如,当你在 meta 上创建一个主题时,会向 https://meta.discourse.org/posts.json 发送一个 POST 请求。该请求中包含作者、标题、分类、标签以及帖子内容等信息。
自定义使用 API 通常是为了实现自动化任务,并且经常与其他服务配合使用,例如 Webhooks、脚本、第三方软件和 API。
要使用 API,必须拥有 API 凭证。只需几次点击即可创建,具体步骤请遵循本指南:Create and configure an API key
别再等待,让我们来看一个 API 使用场景的实际示例吧。![]()
创建月度主题
在本示例中,我们将使用 curl 和 cron 在你的论坛上创建一个每月的“自由讨论”主题。这是在线社区中非常流行的做法 ![]()
创建 API 密钥
按照 API 密钥创建指南 进行操作。将 用户级别 设置为“单个用户”。
所选用户将成为月度主题的作者。
然后你可以选择 全局 范围或 细粒度 范围;如果选择后者,则至少需要 主题 → 写入 权限。
记下你生成的 API 密钥。![]()
创建 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\": \"使用 API 创建测试主题\", \"raw\": \"这里是帖子的内容\", \"category\": CATEGORY_ID }"
替换以下内容:
your-discourse.com为你的论坛域名YOUR_API_KEY为你的 API 密钥YOUR_USERNAME为 API 密钥所选的用户名CATEGORY_ID为你希望发布主题的分类 ID
如果一切配置正确,你的论坛上应该会创建一个新的测试主题,如下所示:
大部分工作已经完成!现在我们需要将主题标题和内容更改为更合适的内容,并设置主题创建的周期性。
首先将主题标题从:
使用 API 创建测试主题
更改为:
本月自由讨论 - $(date +\%B)。
同样,将内容从:
使用 API 创建测试主题
更改为:
你在 $(date +\%B -d 'last month') 期间最喜欢和最不喜欢的是什么?\n欢迎分享你的感受并提供建议。🙂
我使用了 date Unix 命令,在标题中插入当前月份名称,在内容中插入上个月的名称。
内容中的 \n 会创建一个新行。
你可以使用命令行运行更新后的 curl 请求。它应该会在你的论坛上创建一个类似这样的新主题:
设置周期性事件
我们将创建一个 cron 任务,在每月的第一天运行 curl 命令。![]()
使用以下命令编辑 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\": \"本月自由讨论 - $(date +\%B)\", \"raw\": \"你在 $(date +\%B -d 'last month') 期间最喜欢和最不喜欢的是什么?\n欢迎分享你的感受并提供建议。🙂\", \"category\": 4 }"
0 0 1 * * 部分定义了命令运行的时间间隔。你可以在这里了解更多语法:https://crontab.guru
完成!现在你的服务器将使用 Discourse REST API、curl 请求和 cron 任务,在每月的第一天自动创建一个“自由讨论”主题。![]()
自动更改主题的颜色方案
让我们让我们的默认主题根据当前季节使用相应的颜色方案
![]()
我们将使用 Ruby 来处理月份检查,并使用 cron 任务来执行脚本。
除了 Ruby 和 cron,我们还有很多其他方法,但本指南也旨在展示如何使用 API 与各种工具配合。
准备主题和颜色方案
选择你要更改颜色方案的主题,并获取其 ID。你可以在主题的 URL 中找到该 ID。例如,这个主题的 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 # 冬季
when 4..6 then 15 # 春季
when 7..9 then 16 # 夏季
else 17 # 秋季
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
刷新浏览器。你主题使用的颜色方案应该会发生变化。![]()
最后一步是创建一个 cron 任务,在每个季节开始的第一天运行此脚本。
如果你不记得如何创建 cron 任务,可以回顾一下 第一个示例。
0 0 1 1,4,7,10 * ruby ~/scripts/seasons.rb
完成!你的论坛现在将在每个新季节开始时呈现新的颜色!
![]()
在 Web 服务器上接收 Web 请求,并使用其数据更新 Discourse 主题
这个示例更复杂一些!![]()
我们的工具是 PHP,这意味着我们假设你在某处有一个已安装 PHP 并正常运行的 Web 服务器。
在本示例中,我们将在一个 PHP 页面上接收来自 Ko-Fi(一个捐赠服务)的 Webhook 负载,然后利用接收到的数据调用 Discourse API,更新主题的标题和内容。
具体来说,它将用捐赠金额和日期更新主题标题,并在列出以往捐赠的表格中添加一行(甚至会自动提升该主题
):
每次用户进行捐赠时,Ko-Fi[2] 都会向我们的 PHP 脚本发送请求。
配置 Ko-Fi
我在 Ko-Fi Webhooks 页面 上进行了配置,只需添加我的 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
}
我们将接收此负载,然后提取我们需要的两个信息:
-
金额 (
3.00),我们将将其四舍五入为整数。 -
时间戳 (
2023-10-19T13:35:06Z),我们将将其格式化为更美观的日期。
接收 Ko-Fi 的负载
首先,我们在 PHP 页面中放置以下代码,以接收来自 Ko-Fi 的请求,确保我们收到的是 POST 请求,并且令牌值与 Ko-Fi Webhooks 页面中提供的匹配。我们还按照前述方式格式化金额和日期。
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' => '🥳 新捐赠:' . $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为正确的主题 IDYOUR_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为正确的帖子 IDYOUR_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' => '🥳 新捐赠:' . $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 "无效的验证令牌。";
}
} else {
http_response_code(405);
echo "仅允许 POST 请求。";
}
?>
让我再次强调本指南开头的警告 ![]()
本指南中的所有代码示例并非旨在展示最佳实践,也不建议直接照搬使用。
为了专注于 API 的使用,我们有意忽略或省略了许多检查、错误处理等内容。
现在我们可以从 Ko-Fi 触发测试请求,看看它如何更新我们的主题,包括标题和内容。![]()
就是这样!
你拥有了一个主题,每当有人在 Ko-Fi 上进行捐赠时,它都会被更新并提升!![]()
本主题为 Wiki。欢迎随时纠正你发现的任何错误,并讨论如何改进本指南。
在此上下文中指特定的 URL。例如:
https://your-discourse.com/posts.json↩︎关于其 API 的一些信息:https://help.ko-fi.com/hc/en-us/articles/360004162298-Does-Ko-fi-Have-an-API-or-Webhook- ↩︎
帖子 ID 可以在 HTML 代码中找到。它是一个带有以下属性的
<article>元素:data-post-id="POST_ID"↩︎





