Поделитесь вашими сценариями использования REST API Discourse 🧑‍💻

Всем привет :slight_smile:

Многие используют API Discourse для различных целей: от автоматизации задач до взаимодействия с другими приложениями.

Расскажите, пожалуйста, как вы его используете?

  • На каком этапе?

  • Какие технологии, программное обеспечение или языки программирования вы применяете для этого?

Вот несколько примеров того, как использую его я:

  • Я настраиваю вебхук для элемента «reviewable», который запускает PHP-скрипт, использующий API Discourse для автоматического удаления спамеров. Учитывая большое количество помеченных сообщений ежедневно в моём сообществе и точность детекции спама в 100%, это значительно облегчает работу администраторов и модераторов, так как им больше не нужно вручную проверять большинство таких аккаунтов (хотя я не рекомендую использовать такой метод без тщательного обдумывания и тестирования, как сделал это я).

  • Использую вебхук от Ko-Fi (сервис для сбора пожертвований), который через PHP-скрипт обращается к API Discourse для обновления значения настройки компонента темы. Цель — отображать на Discourse прогресс-бар сбора пожертвований, который обновляется в реальном времени.

  • Применяю его для тестирования с помощью Insomnia. Это может быть заполнение тестового экземпляра конкретным контентом, проверка запросов при планировании новых проектов, помощь людям на meta и многое другое.

А как используете его вы? Не стесняйтесь приводить подробные примеры, уверен, что есть много интересных кейсов, о которых стоит узнать :slight_smile:


Тема с описанием API: Discourse REST API Documentation
Официальная документация: https://docs.discourse.org/

Я веду форум для любителей метеорологии (наблюдателей за погодой). Мы с ещё одним человеком предоставляем поток данных о погоде, который сотни людей по всему миру используют для создания собственных гиперлокальных прогнозов.

Один из наших пользователей написал сложные статистические скрипты для проверки качества своих прогнозов, а также доступности потоков данных. Если его скрипты обнаруживают пропущенные, повреждённые или задержанные данные в потоках, они создают пост в категории форума, предназначенной для поддержки программного обеспечения для прогнозирования. Это позволяет другим прогнозистам узнать о проблеме, которая может повлиять и на них.

Скрипты для обнаружения аномалий в потоках данных написаны на PHP. Они генерируют JSON-файл с описанием проблемы, а затем используют cURL для отправки поста через API.

Недавно я провёл много экспериментов с различными платформами, позволяющими соединять шаги в цепочку, и хочу поделиться одной, которая меня вдохновила: распознавание текста на изображениях (OCR) с последующим добавлением результата в пост на Discourse!

Моя тема в песочнице показывает, как это работает: https://notes.maiki.interi.org/t/testing-ocr-calls/403

Первый вариант я реализовал на Pipedream и объясню, как это сделать, пройдя по шагам. На этом сервисе есть бета-функция для обмена рабочими процессами, и следующий пример доступен по адресу: https://pipedream.com/new?h=tch_3Z6fa9.

:information_source: Хотя это могло бы стать подробным руководством по использованию Pipedream с Discourse, я ограничусь кратким описанием, так как уже перешёл на другую платформу и позже расскажу об этом подробнее. :slight_smile:

Шаги

Примерная схема такая: отправить URL изображения в Google Cloud Vision API, обработать результаты через ChatGPT, а затем добавить итог в пост на Discourse.

Триггер

Screenshot 2023-08-08 at 11-23-21 OCR Test - Pipedream

Это предоставляет вебхук для отправки данных. В Discourse я создал вебхук с двумя конкретными настройками:

Screenshot 2023-08-08 at 11-24-41 Admin - notes

Запуск только при событиях постов означает, что моя начальная тема не запустит процесс; это полезно, так как я планирую использовать темы как контейнеры для применения внешних функций (я называю их «функциональными заметками»).

Запуск только по указанному тегу позволяет использовать теги для управления тем, какие вебхуки создаются для каждой темы; обычно у меня будет только один тег «functions», чтобы упростить логику процесса.

Вебхук отправляет полезную нагрузку с большим количеством информации, и позже в процессе мы будем использовать ID темы и поста.

Завершение по условию

Это шаг для проверки, включена ли причина редактирования. Если да, рабочий процесс останавливается.

На последнем шаге я обновляю пост и включаю причину редактирования, и эта проверка гарантирует, что я не буду бесконечно обновлять пост:sweat_smile:

:information_source: Одна из причин, по которой я перестал использовать Pipedream, заключалась в том, что мои проверки вебхуков съедали кредиты на сервисе. Я не думаю, что должен платить за условную обработку вебхука, поэтому я перешёл к другой платформе…

Извлечение URL изображения

Для этого теста я решил, что каждый пост будет содержать одно загруженное изображение. Этот шаг проверяет значение «cooked» и использует следующее регулярное выражение для извлечения URL:

/https?:\/\/[^\s"]+/

Вызов Google Cloud Vision API

Это шаг с пользовательским кодом на Pipedream. Готовые компоненты не делали того, что мне нужно, и у сервиса также есть помощник по коду, который может писать код по промпту; так как эти вызовы API просты, их легко создать этим методом.

Он принимает значение предыдущего шага ({{steps.extract_by_regular_expression.$return_value[0].match}}), и вот код:

import { axios } from "@pipedream/platform";

export default defineComponent({
  props: {
    imageUrl: {
      type: "string",
      label: "Image URL",
      description: "URL of the image to be processed by Google Vision API",
    },
    apiKey: {
      type: "string",
      label: "API Key",
      description: "Your Google Cloud API Key",
      secret: true,
    },
  },
  async run() {
    const url = `https://vision.googleapis.com/v1/images:annotate?key=${this.apiKey}`;
    const body = {
      requests: [
        {
          image: {
            source: {
              imageUri: this.imageUrl,
            },
          },
          features: [
            {
              type: "TEXT_DETECTION",
            },
          ],
        },
      ],
    };

    const config = {
      method: "POST",
      url,
      data: body,
    };

    const response = await axios(this, config);
    return response;
  },
});

ChatGPT для редактирования

Принимает вывод предыдущего шага ({{steps.google_cloud.$return_value.responses[0].fullTextAnnotation.text}}) и передаёт его как сообщение пользователя. Для системного сообщения я использую:

Вы читаете вывод API распознавания изображений, который обнаружил текст на изображении. Проверьте сообщение и отредактируйте его для ясности. Верните только отредактированный текст без комментариев.

Добавление в пост на Discourse

Ещё один раздел с пользовательским кодом, так как готовые действия Discourse в Pipedream покрывают лишь несколько сценариев (создание темы или поста), а я хочу добавить текст в пост.

Сначала вот код:

import { axios } from "@pipedream/platform";

export default defineComponent({
  props: {
    discourse: {
      type: "app",
      app: "discourse",
    },
    postId: {
      type: "string",
      label: "Post ID",
      description: "The ID of the post to append text to",
    },
    text: {
      type: "string",
      label: "Text",
      description: "The text to append to the post",
    },
    editReason: {
      type: "string",
      label: "Edit Reason",
      description: "The reason for editing the post",
      optional: true,
    },
  },
  async run({ steps, $ }) {
    const url = `https://${this.discourse.$auth.domain}/posts/${this.postId}.json`;
    const response = await axios($, {
      method: "GET",
      url: url,
      headers: {
        "Api-Username": `${this.discourse.$auth.api_username}`,
        "Api-Key": `${this.discourse.$auth.api_key}`,
      },
    });

    const updatedText = `${response.raw} ${this.text}`;

    return await axios($, {
      method: "PUT",
      url: url,
      headers: {
        "Api-Username": `${this.discourse.$auth.api_username}`,
        "Api-Key": `${this.discourse.$auth.api_key}`,
      },
      data: {
        post: {
          raw: updatedText,
          edit_reason: this.editReason,
        },
      },
    });
  },
});

Свойства для этого шага заполняются следующим образом:

ID поста

Извлекает ID поста из исходной полезной нагрузки: {{steps.trigger.event.body.post.id}}

Это используется для прямого редактирования этого поста.

Текст
---

<blockquote>
 {{steps.chat.$return_value.generated_message.content}}
</blockquote>

[details="Detected text"]
{{steps.google_cloud.$return_value.responses[0].textAnnotations[0].description}}
[/details]

По сути, я хочу добавить горизонтальную линию под каждым изображением, блок-цитату с отредактированным текстом и блок деталей для просмотра исходного вывода.

Так как каждый пост будет содержать одно изображение, это работает очень легко. Интересно, как сделать это с несколькими изображениями сразу? :thinking:

Причина редактирования

OCR Text Detection

Это добавляется как причина редактирования при обновлении поста, что предотвратит цикл обновлений поста из-за шага в начале. :point_up: :recycle: :ng:

:information_source: Я считаю крайне полезным всегда указывать причину редактирования, особенно при работе с внешними сервисами.


И всё! Как вы можете видеть из моей песочницы, это работает довольно хорошо!

У меня скоро поездка, и я планирую доработать редактирование через OpenAI так, чтобы оно также переводило текст на английский при необходимости; это один из вариантов, который я бы добавил в системный промпт для этого рабочего процесса.