Создание новых тем, постов и личных сообщений через IFTTT

Хотите использовать IFTTT для создания новых тем, постов и личных сообщений? Давайте начнём!

С помощью Maker Webhooks сервиса IFTTT мы можем выполнять вызовы Discourse API. Для этого сначала нужно сгенерировать API-ключи. Вы можете создать API-ключи в панели администратора по адресу /admin/api/keys.

Также можно сгенерировать пользовательские API-ключи через страницы администрирования пользователей.

Теперь создайте новый апплет в IFTTT и выберите предпочитаемую службу-триггер. В качестве примера я использую службу Google Calendar.

Затем я выбираю триггер Любое новое событие добавлено.

Чтобы подключить ваш триггер к Discourse, выберите в качестве службы действия Maker Webhooks и действие Выполнить веб-запрос.

Теперь заполните поля действия следующим образом.

  • URL (обязательно): https://discourse.example.com/posts.json

  • Метод (обязательно): POST

  • Тип содержимого: application/json

  • Дополнительные заголовки:

Api-Key: [ВАШ_API_КЛЮЧ]
Api-Username: [ИМЯ_ПОЛЬЗОВАТЕЛЯ_API]

:warning: Важно: Учётные данные API должны передаваться в заголовках HTTP (Api-Key и Api-Username), а не в параметрах запроса URL. Discourse не принимает аутентификацию по API-ключу через параметры запроса в POST-запросах. Служба Maker Webhooks в IFTTT поддерживает пользовательские заголовки — используйте поле Дополнительные заголовки для их добавления.

  • Тело запроса:
{
 "title": "{{Title}}",
 "raw": "{{Description}}\n\nМесто: {{Where}}\nВремя: {{Starts}} - {{Ends}}",
 "category": 4,
 "created_at": "{{CreatedAt}}"
}

В тексте тела запроса вы увидите множество полей с двойными скобками {{ }}. Эти поля (источники содержимого) будут меняться в зависимости от триггера службы. Выберите их с помощью кнопки Ингредиент ниже.

Вы можете изменять поля title и raw в теле JSON-запроса по своему усмотрению, добавляя необходимый текст. Найдите идентификатор категории на вашем сайте по адресу /site.json и укажите его в поле категории. Теперь нажмите кнопку Создать действие, чтобы завершить создание апплета. После создания апплета может потребоваться некоторое время для его активации.

Готово :sunglasses:. Теперь новая тема будет создаваться всякий раз, когда в вашем Google Calendar появится новое событие :calendar_spiral:.


Чтобы создать ответ в существующей теме вместо создания новой, измените тело запроса следующим образом (используя topic_id вместо category):

{
 "title": "{{Title}}",
 "raw": "{{Description}}\n\nМесто: {{Where}}\nВремя: {{Starts}} - {{Ends}}",
 "topic_id": 4,
 "created_at": "{{CreatedAt}}"
}

Для создания нового личного сообщения:

{
 "title": "{{Title}}",
 "raw": "{{Description}}\n\nМесто: {{Where}}\nВремя: {{Starts}} - {{Ends}}",
 "target_usernames": "discourse1,discourse2",
 "archetype": "private_message",
 "created_at": "{{CreatedAt}}"
}

Этим же способом вы можете выполнять запросы к API Discourse с помощью любых других служб действий IFTTT.

22 лайка

Интересно, не является ли эта опция больше бесплатной и доступна ли она только как премиум-функция для разработчиков?

1 лайк

Согласно документации API Discourse, параметры Api_username и Api_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"));

// Попытка декодировать входящие необработанные данные POST из JSON.
$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" => 'Конечная точка Discourse должна быть указана в теле JSON!'));
    die();
}

if (empty($payload['api_key'])) {
    echo json_encode(array("error" => 'API-ключ Discourse должен быть указан в теле JSON!'));
    die();
}

if (empty($payload['api_username'])) {
    echo json_encode(array("error" => 'Пользователь API Discourse должен быть указан в теле JSON!'));
    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;
?>

Вы можете узнать об этом больше здесь: https://community.jamaicans.dev/t/generate-new-topics-posts-and-pm-via-discourse-relay-api-script/176

2 лайка

Я тоже в такой же ситуации, пытаясь настроить апплет IFTTT для публикации элементов, отмеченных определённым тегом в Pinboard (у меня есть другие апплеты для публикации в Mastodon, где я могу передавать токен как заголовок, а не через параметры GET).

Мои посредственные навыки PHP позволяют понять, как работает ваш код. Мой вопрос связан с тем, что я менее знаком с сервером Discourse: где можно разместить этот скрипт? Нужно ли размещать его на том же сервере, чтобы избежать проблем CORS?

Или мне стоит рассмотреть другую интеграционную платформу вместо IFTTT?

Ему просто нужно быть размещенным на сервере, который может принимать запросы от IFTTT и общаться с вашим экземпляром Discourse через функции curl. Он просто инициирует тот же тип запроса, что и веб-интерфейс Discourse. :slight_smile:

1 лайк

Спасибо. Похоже, у меня есть доступ к Zapier, у которого интеграции лучше.