DEV: Allow passing a class to add_automation_scriptable

This commit modify's discourse-automation's add_automation_scriptable
plugin API method to allow passing a class instead of a block.
This helps with readability and separation, since then all of the
scripts do not need to be defined in plugin.rb

There are two requirements for the class:

1. It must have a `self.call` method
2. This `self.call` method must wrap its contents in `proc {}`

This way a block is returned from the class and the rest of
it is evaluated in the same way the block from add_automation_scriptable
usually is.
This commit is contained in:
Martin Brennan 2024-10-08 15:44:24 +10:00
parent 974a3bfc41
commit 7855218797
No known key found for this signature in database
GPG Key ID: BD981EFEEC8F5675
5 changed files with 58 additions and 30 deletions

View File

@ -2,8 +2,8 @@
module DiscourseAutomation
module PluginInstanceExtension
def add_automation_scriptable(name, &block)
reloadable_patch { DiscourseAutomation::Scriptable.add(name, &block) }
def add_automation_scriptable(name, scriptable_class = nil, &block)
reloadable_patch { DiscourseAutomation::Scriptable.add(name, scriptable_class, &block) }
end
def add_automation_triggerable(name, &block)

View File

@ -285,9 +285,13 @@ module DiscourseAutomation
end
end
def self.add(identifier, &block)
def self.add(identifier, scriptable_class = nil, &block)
@all_scriptables = nil
define_method("__scriptable_#{identifier}", &block)
if block_given?
define_method("__scriptable_#{identifier}", &block)
else
define_method("__scriptable_#{identifier}", scriptable_class.call)
end
end
def self.remove(identifier)

View File

@ -26,12 +26,25 @@ describe "Core extensions" do
end
describe "#add_automation_scriptable" do
class MyScriptableClass
def self.call
proc { puts "Hello world" }
end
end
it "adds the scriptable" do
plugin = Plugin::Instance.new nil, "/tmp/test.rb"
plugin.add_automation_scriptable(:foo) {}
expect(DiscourseAutomation::Scriptable.all).to include(:__scriptable_foo)
end
it "adds the scriptable using a class" do
plugin = Plugin::Instance.new nil, "/tmp/test.rb"
plugin.add_automation_scriptable(:foo, MyScriptableClass)
expect(DiscourseAutomation::Scriptable.all).to include(:__scriptable_foo)
end
end
end

View File

@ -0,0 +1,36 @@
# frozen_string_literal: true
module Chat
class SendMessageAutomationScript
def self.call
proc do
field :chat_channel_id, component: :text, required: true
field :message, component: :message, required: true, accepts_placeholders: true
field :sender, component: :user
placeholder :channel_name
triggerables %i[recurring topic_tags_changed post_created_edited]
script do |context, fields, automation|
sender = User.find_by(username: fields.dig("sender", "value")) || Discourse.system_user
channel = Chat::Channel.find_by(id: fields.dig("chat_channel_id", "value"))
placeholders = { channel_name: channel.title(sender) }.merge(
context["placeholders"] || {},
)
creator =
::Chat::CreateMessage.call(
chat_channel_id: channel.id,
guardian: sender.guardian,
message: utils.apply_placeholders(fields.dig("message", "value"), placeholders),
)
if creator.failure?
Rails.logger.warn "[discourse-automation] Chat message failed to send:\n#{creator.inspect_steps.inspect}\n#{creator.inspect_steps.error}"
end
end
end
end
end
end

View File

@ -457,32 +457,7 @@ after_initialize do
}
end
add_automation_scriptable("send_chat_message") do
field :chat_channel_id, component: :text, required: true
field :message, component: :message, required: true, accepts_placeholders: true
field :sender, component: :user
placeholder :channel_name
triggerables %i[recurring topic_tags_changed post_created_edited]
script do |context, fields, automation|
sender = User.find_by(username: fields.dig("sender", "value")) || Discourse.system_user
channel = Chat::Channel.find_by(id: fields.dig("chat_channel_id", "value"))
placeholders = { channel_name: channel.title(sender) }.merge(context["placeholders"] || {})
creator =
::Chat::CreateMessage.call(
chat_channel_id: channel.id,
guardian: sender.guardian,
message: utils.apply_placeholders(fields.dig("message", "value"), placeholders),
)
if creator.failure?
Rails.logger.warn "[discourse-automation] Chat message failed to send:\n#{creator.inspect_steps.inspect}\n#{creator.inspect_steps.error}"
end
end
end
add_automation_scriptable("send_chat_message", Chat::SendMessageAutomationScript)
add_api_key_scope(
:chat,