通过 IFTTT 生成新主题、帖子和私信

想使用 IFTTT 创建新主题、帖子和私信吗?让我们开始吧!

通过 IFTTT 服务的 Maker Webhooks,我们可以调用 Discourse API。为此,我们需要先生成 API 密钥。您可以在管理面板的 /admin/api/keys 处创建 API 密钥。

此外,我们还可以通过用户管理页面生成特定于用户的 API 密钥。

现在,在 IFTTT 上 创建新应用,然后选择您喜欢的触发服务。例如,我现在使用的是 Google 日历 服务。

然后我选择 添加任何新事件 作为触发器。

要将触发器与 Discourse 连接,请选择 Maker Webhooks 作为操作服务,并选择 发起网络请求 操作。

现在按如下方式填写操作字段。

  • URL(必填): https://discourse.example.com/posts.json
  • 方法(必填): POST
  • 内容类型: application/json
  • 其他标头:
Api-Key: [YOUR_API_KEY]
Api-Username: [API_USERNAME]

:warning: 重要提示: API 凭据必须作为 HTTP 标头(Api-KeyApi-Username)发送,而不是作为 URL 查询参数。Discourse 不接受通过查询参数进行的 POST 请求 API 密钥身份验证。IFTTT 的 Maker Webhooks 服务支持自定义标头 — 请使用 其他标头 字段添加它们。

  • 请求体:
{
 "title": "{{Title}}",
 "raw": "{{Description}}\n\nPlace: {{Where}}\nAt: {{Starts}} - {{Ends}}",
 "category": 4,
 "created_at": "{{CreatedAt}}"
}

在请求体文本中,您可以看到许多带有双括号 {{ }} 的字段。这些字段(内容源)将随每个服务触发器而变化。请从下方的 参数 按钮中选择它们。

您可以根据需要编辑 JSON 请求体中的 titleraw 字段及其周围的文本。从您网站的 /site.json URL 中找到类别 ID 并将其放入类别字段中。现在点击 创建操作 按钮以创建应用。应用创建后,可能需要一些时间才能生效。

完成了 :sunglasses:。现在,每当您的 Google 日历创建新事件时,就会创建一个新主题 :calendar_spiral:


要创建对现有主题的回复而不是创建新主题,请将请求体文本更改如下(使用 topic_id 代替 category):

{
 "title": "{{Title}}",
 "raw": "{{Description}}\n\nPlace: {{Where}}\nAt: {{Starts}} - {{Ends}}",
 "topic_id": 4,
 "created_at": "{{CreatedAt}}"
}

创建新私信:

{
 "title": "{{Title}}",
 "raw": "{{Description}}\n\nPlace: {{Where}}\nAt: {{Starts}} - {{Ends}}",
 "target_usernames": "discourse1,discourse2",
 "archetype": "private_message",
 "created_at": "{{CreatedAt}}"
}

使用相同的方法,您可以通过任何其他 IFTTT 操作服务 发起 Discourse API 请求。

22 个赞

I wonder if this option is no longer free and only available as a premium for developers ?

1 个赞

根据 Discourse API 文档Api_usernameApi_key 必须通过 HTTP 请求头发送。将它们作为 GET 参数发送是无效的。

我尝试过但失败了,因此无法按照这里的说明使用 IFTTT……

不过,我最终编写了一个简单的自定义 PHP 脚本,作为中继钩子,允许数据以正确的配置发送到 Discourse。

代码
<?php
header('Content-Type: application/json');

// 确保请求方法是 POST。
if (strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0) {
    echo json_encode(array("error" => '请求方法必须是 POST!'));
}

// 确保 POST 请求的内容类型已设置为 application/json
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
if (strcasecmp($contentType, 'application/json') != 0) {
    echo json_encode(array("error" => '内容类型必须是: application/json'));
}

// 接收原始 POST 数据。
$content = trim(file_get_contents("php://input"));

// 尝试解码传入的原始 JSON POST 数据。
$payload = json_decode($content, true);

// 如果 json_decode 失败,说明 JSON 无效。
if (!is_array($payload)) {
    echo json_encode(array("error" => '接收到的内容包含无效的 JSON!'));
    die();
}

if (empty($payload['discourse_endpoint'])) {
    echo json_encode(array("error" => '必须在 JSON 主体中提供 Discourse 端点!'));
    die();
}

if (empty($payload['api_key'])) {
    echo json_encode(array("error" => '必须在 JSON 主体中提供 Discourse API 密钥!'));
    die();
}

if (empty($payload['api_username'])) {
    echo json_encode(array("error" => '必须在 JSON 主体中提供 Discourse API 用户名!'));
    die();
}

$discourse_endpoint = $payload['discourse_endpoint'];
$api_key = $payload['api_key'];
$api_user = $payload['api_username'];

unset($payload['discourse_endpoint']);
unset($payload['api_key']);
unset($payload['api_username']);

$data_string = json_encode($payload);

$ch = curl_init($discourse_endpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    "Api-key: $api_key",
    "Api-username: $api_user",
    'Content-Length: ' . strlen($data_string)
));
$result = curl_exec($ch);

echo $result;
?>

你可以在此处了解更多相关信息:Generate new topics, posts and PM via Discourse Relay API Script - php - CTC Community Forum

2 个赞

我在这里遇到了同样的问题,正试图设置一个IFTTT小程序,将带有特定标签的书签发布到Pinboard(我还有其他小程序将内容发布到Mastodon,在那里我可以将令牌作为标头项传递,而不是GET参数)。

我平庸的PHP技能完全理解你的代码是如何工作的,我的问题是,由于我对Discourse服务器不太了解,我应该把脚本放在哪里?它需要放在同一台服务器上以避免CORS问题吗?

或者我应该考虑使用IFTTT以外的其他集成中间平台吗?

它只需要托管在一个能够接受来自IFTTT的请求并且能够通过curl函数与你的Discourse实例通信的服务器上。它只是启动了与Discourse Web界面相同的请求类型。 :slight_smile:

1 个赞

谢谢。看起来我可以使用 Zapier,它有更好的集成。