カスタムオートメーションを作成

:information_source: これはドラフトであり、追加の作業が必要になる場合があります。

語彙

  • trigger: トリガーの名前を表します。例: user_added_to_group
  • triggerable: トリガーに関連付けられたコードロジックを表します。例: triggers/user_added_to_group_.rb
  • script: スクリプトの名前を表します。例: send_pms
  • scriptable: スクリプトに関連付けられたコードロジックを表します。例: scripts/send_pms.rb

プラグインAPI

add_automation_scriptable(name, &block)
add_automation_triggerable(name, &block)

Scriptable API

field

field :name, component: を使用すると、自動化のUIにカスタマイズ可能な値を追加できます。

有効なコンポーネントのリスト:

# foo は一意で、フィールドの名前を表します。

field :foo, component: :text # テキスト入力フィールドを生成します
field :foo, component: :list # ユーザーが値を入力できる複数選択テキスト入力を生成します
field :foo, component: :choices, extra: { content: [ {id: 1, name: 'your.own.i18n.key.path' } ] } # カスタムコンテンツを持つコンボボックスを生成します
field :foo, component: :boolean # チェックボックス入力を生成します
field :foo, component: :category # カテゴリ選択肢を生成します
field :foo, component: :group # グループ選択肢を生成します
field :foo, component: :date_time # 日時ピッカーを生成します
field :foo, component: :tags # タグ選択肢を生成します
field :foo, component: :user  # ユーザー選択肢を生成します
field :foo, component: :pms  # 1つ以上のPMテンプレートを作成できます
field :foo, component: :categories  # ゼロ個以上のカテゴリを選択できます
field :foo, component: :key-value  # キーと値のペアを作成できます
field :foo, component: :message  # 置換可能な変数を使用してPMを作成できます
field :foo, component: :trustlevel  # 1つ以上の信頼レベルを選択できます
triggerables and triggerable!
# スクリプトで許可されるトリガー可能なリストを定義します
triggerables %i[recurring]

# スクリプトのトリガー可能なものを強制し、フィールドに特定の状態を強制することもできます
field :recurring, component: :boolean
triggerable! :recurring, state: { foo: false }
placeholders
# `%%sender%%` のプレースホルダー構文を使用して、テキスト内でキーを置換可能としてマークします
placeholder :sender

プレースホルダーの値を提供し、input = utils.apply_placeholders(input, { sender: 'bob' }) を使用して置換を適用するのはスクリプトの責任です。

script

これは自動化の中心であり、すべてのロジックが発生する場所です。

# context は自動化がトリガーされたときに送信され、トリガーによって大きく異なる場合があります
script do |context, fields, automation|
end

ローカライゼーション

使用する各フィールドは、i18nキーに依存し、トリガー/スクリプトの名前空間に属します。

たとえば、このコンテンツを持つスクリプト可能なもの:

field :post_created_edited, component: :category

client.en.yml で次のキーが必要になります:

en:
  js:
    discourse_automation:
      scriptables:
        post_created_edited:
          fields:
            restricted_category:
              label: Category
              description: Optional, allows to limit trigger execution to this category

ここで、description はオプションです。


このドキュメントはバージョン管理されています - github で変更を提案してください。

「いいね!」 7

新しいトピックだと知ったとき、もっと詳細が共有されたのかと思って興奮しました!:laughing:

Rubyでプログラミングはしませんが、ワークフローの自動化に非常に興味がある者として、例を通してもう少し理解できるのではと期待していました…

:thinking:

Developing Discourse Plugins - Part 1 - Create a basic plugin から始める必要がありそうです… :sweat_smile:

「いいね!」 8

このセクションは、既存のものを利用するために知る必要がないように、プラグイントピックから切り取っただけです。:slight_smile:

これがもう少し段階的なものになれば素晴らしいと思いますが、私もそう思います。コミュニティの助けを求める信号を送りました。このような経験をした人はいるでしょうか?:crossed_fingers:

「いいね!」 5

こんにちは、世界 の例があると嬉しいです。
スクリプトはどこに保存すればよいですか?少し実験してみたいです。

「いいね!」 4

このプラグインと組み合わせて、カスタムスクリプトを記述できると思います。

おそらく、調べるのに最も良い場所は、Data Explorer プラグインに追加された自動化スクリプトでしょう: discourse-data-explorer/plugin.rb at main · discourse/discourse-data-explorer · GitHub プラグインの既存のスクリプトとトリガーを見る価値もあります: https://github.com/discourse/discourse-automation/tree/main/lib/discourse_automation

Meta にカスタム自動化の追加に関する情報はあまりないので、ユーザーのアクティビティ概要メール設定を更新するスクリプトを追加する plugin.rb ファイルの例を以下に示します。このスクリプトは、Automation プラグインの ‘user_added_to_group’ または ‘user_removed_from_group’ トリガーによってトリガーできます。

# frozen_string_literal: true

# name: automation-script-example
# about: An example of how to add a script to an automation
# version: 0.0.1
# authors: scossar

enabled_site_setting :automation_script_example_enabled

after_initialize do
  reloadable_patch do
    if defined?(DiscourseAutomation)
      DiscourseAutomation::Scriptable::USER_UPDATE_SUMMARY_EMAIL_OPTIONS =
        "user_update_summary_email_options"
      add_automation_scriptable(
        DiscourseAutomation::Scriptable::USER_UPDATE_SUMMARY_EMAIL_OPTIONS
      ) do

        field :email_digests, component: :boolean

        version 1
        triggerables [:user_added_to_group, :user_removed_from_group]

        script do |context, fields, automation|
          if automation.script == "user_update_summary_email_options" && (context["kind"] == "user_added_to_group" || context["kind"] == "user_removed_from_group")
            user_id = context["user"].id
            digest_option = fields.dig("email_digests", "value")
            user_option = UserOption.find_by(user_id: user_id)

            if (user_option)
              user_option.update(email_digests: digest_option)
            end
          end
        end
      end
    end
  end
end

プラグインの全コードはこちらです: GitHub - scossar/automation-script-example: An example of how to add a custom script to the Discourse Automation plugin..

:warning: このコードを本番サイトでそのまま使用しないでください。今晩初めて Automation コードを見ました。コードに関する潜在的な問題についてフィードバックがあれば、この投稿と GitHub リポジトリを更新します。

編集: 私の懸念は、‘user_added_to_group’ または ‘user_removed_from_group’ トリガーによって複数の自動化スクリプトがトリガーされるケースをどのように最も適切に処理するかということでした。プラグインの最初のバージョンでは次をチェックしていました。

fields.has_key?("email_digests")

しかし、それはかなり不安定に感じられました。email_digests キーを持つ別のスクリプトが追加された場合はどうなるでしょうか?

更新されたコードは、コードブロックに automation パラメータを渡し、次をチェックします。

automation.script == "user_update_summary_email_options"

これにより、スクリプトが誤った自動化に対して実行されないことが保証されるはずです。
…さらに考えてみると、スクリプトが設定されていない自動化によってトリガーされる可能性は低いでしょう :slight_smile:

「いいね!」 7

私も知りたいです。@simonのようなリポジトリを作成した場合、プラグインはそれにどのようにアクセスするのでしょうか?

プラグイン全体をフォークして、https://github.com/discourse/discourse-automation/tree/main/lib/discourse_automation/scripts にある既存のものと一緒にドロップする必要があるのでしょうか?それとも、もっとエレガントな方法がありますか?

「いいね!」 1

他のDiscourseプラグインと同様にインストールする必要があります: Discourseにプラグインをインストールする。したがって、Automationプラグインをインストールし、カスタムスクリプトを追加するプラグインをインストールすることになります。それが機能する理由は、ここに定義されているメソッドによるものです: https://github.com/discourse/discourse-automation/blob/main/lib/plugin/instance.rb。上記の例のコードでは、`add_automation_scriptable`を呼び出すことでカスタムスクリプトが追加されていることがわかります。

注意: GitHubリポジトリから提供されている自動化の例をインストールしないでください。カスタムスクリプトの拡張方法の例としてのみ参照してください。(ここにリンクしたことを忘れ、私のDiscourse Automationプラグインのフォークバージョンでのみ機能するように更新しました。ここにリンクしたコードはまだ有効です: Create custom Automations - #6 by simon

私の懸念は杞憂でした。この条件は不要です:

if automation.script == "user_update_summary_email_options" && (context["kind"] == "user_added_to_group" || context["kind"] == "user_removed_from_group")

まもなく例を更新します。

「いいね!」 4

カスタムオートメーションには、セルフホストインストール(または、Discourseがインストールされているファイルシステムへの直接バックエンドアクセス)が必要であると理解してよろしいでしょうか?

「いいね!」 2

はい、しかし、コミュニティビルドに新しい自動化スクリプトをマージすることには非常に前向きです。どのようなものを構築したいと考えていますか?

「いいね!」 6

具体的には、投稿内の特定の文字列(正確な構文にはあまりこだわりませんが、プレーンテキストの @ref `Random.rand!` のようなもの)を、Random.rand! のようなフォーマットされたリンクに置き換える方法を探しています。正確なURLを検索することは、数万ものターゲットが存在する複雑なプロセスであり、正規表現(Auto linkify words/watched words のように)では完全に不可能であり、Turing完全なプラグインのような環境であればはるかに簡単です。そのため、自動化でこれが可能かどうか疑問に思っていました。

そこで、投稿編集後のアクションを探していました。これは、@system ユーザーが前の投稿全体を引用したときに行うこと(こちらを参照)に似ています。これは「投稿作成時」(または「投稿後のクック後」)にトリガーされる「投稿編集」スクリプトになりますが、自動化フレームワークではそのような一般的な「投稿編集」アクションは許可されないと思います。これは、コミュニティビルドでは意味をなさない、非常に具体的なリンクからJuliaドキュメントへのカスタム自動化である必要があると思います。

カスタム自動化に関して、私は間違った方向に進んでいるのかもしれません。可能性を探っていただけです。もちろん、プログラミング言語愛好家のためのフォーラムとして、勇敢なユーザーはすでに、これを行うためにDiscourse APIを使用できるプログラミングボットについて考えています。

「いいね!」 1

ここでは、自動化が求めているものではないと思います。なぜなら、ここで重要だと感じるのは「エンドユーザー」の体験だからです。自動化では、これは事後でしか置き換えられません。

このような問題を考えると、カスタムプラグインまたはテーマコンポーネントのいずれかを選択することをお勧めします。

テーマコンポーネントは次のように機能します。

  1. ユーザーが ^Rand と入力します。
  2. ホストしているバックエンドサービスにHTTP呼び出しが行われ、URLを含むすべてのオプションがリストされます。
  3. ユーザーが目的のものを選択してEnterキーを押します。
  4. Markdownが [Random.rand!](https://docs.julialang.org/en/v1/stdlib/Random/#Random.rand!) に置き換えられます。

Markdownパイプラインを修正するプラグインは、oneboxと同様に機能し、入力時に自動的にリンクを作成し、元の構文を残します。例: ^Random.rand

linkifyが理想的ではないことは理解しています。発見が難しく、ウェブサイトをホストする必要がある場合があるため、lookup.docs.julialang.org?q=Random.rand! に正規化する必要があります。

確かに非常に興味深い問題です。テーマコンポーネントのUXはここで妥当なものになると思います。

「いいね!」 2

それは素晴らしいですね。ご意見とポインタをありがとうございます!さらに質問(または回答 :slight_smile: )がある場合は、別のトピックで取り上げます。

「いいね!」 2

投稿の変更時にトリガーされるカスタムプラグインを作成するのが適切だと思います。単純なトリガーである今回のケースでは、オートメーションプラグインで複雑に設定するよりも、プラグインを作成する方が簡単でしょう。

「いいね!」 1

@McUles および @nathank はお探しの情報を見つけましたか?

カスタムオートメーションを機能させるために、以下のファイルを変更する必要がありました。

カスタムオートメーションスクリプトを作成しました

更新: server.en.yml

yml ファイルの scriptables セクションにカスタムオートメーションの名前、タイトル、説明を追加しました。

更新: client.en.yml

scriptables にカスタムオートメーションの名前を追加しました。「field」キーワードを追加しました。field キーワードの中に「field_name」を、その後に「label」と「description」を追加しました。

更新: scripts.rb

スクリプトのリストにカスタムオートメーション名を追加しました。例: FILE_NAME = “file_name”

更新: plugin.rb

「after_initialize do」の中に、カスタムオートメーションスクリプトへのパスを追加しました。例: 「lib/discourse_automation/scripts/file_name」

そこにあるものを完全に理解していません。これらはAutomationsプラグインへの変更ですか、それともカスタムオートメーションを含む姉妹プラグインの重要なコンポーネントですか?

これをOPに統合していただけると幸いです。

「いいね!」 2

それです。あなたの質問に対する答えを本当によく知らなかったので、答えを見つける方法と、「どこかに例はありますか?」という質問への答えを以下に示します。

まず、これを取得します: GitHub - discourse/all-the-plugins

次に、「add_automation_scriptable」のようなもので grep を実行すると、何がそれを使用しているかを知ることができます。

 (main) pfaffman@noreno:~/src/discourse-repos/all-the-plugins/official$ grep -r add_automation_scriptable
discourse-assign/plugin.rb:    add_automation_scriptable("random_assign") do
discourse-chat-integration/plugin.rb:    add_automation_scriptable("send_slack_message") do
discourse-chat-integration/plugin.rb:    add_automation_scriptable("send_chat_integration_message") do
discourse-data-explorer/plugin.rb:      add_automation_scriptable("recurring_data_explorer_result_pm") do
discourse-data-explorer/plugin.rb:      add_automation_scriptable("recurring_data_explorer_result_topic") do

したがって、discourse-assign または data-explorer を調べてみてください。

「いいね!」 2