discourse/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/actions.rb
Régis Hanol 3c31884b79 FIX: match discobot triggers on cooked version
In French, the help trigger has a raw content of "afficher l'aider" which is then cooked into "afficher l’aide" (note the different quote character).
Since we were checking the raw content of the trigger against the cooked version of the post, this trigger never worked in French.

This changes so that we cook the trigger before checking in against the cooked version of the post.

DEV: new 'discobot_username' method that is used everywhere instead of 'discobot_user.username' / 'discobot_user.username_lower'
2020-06-25 13:29:55 +02:00

117 lines
2.8 KiB
Ruby

# frozen_string_literal: true
module DiscourseNarrativeBot
module Actions
TIMEOUT_DURATION = 900 # 15 mins
def discobot_user
@discobot ||= User.find(-2)
end
def discobot_username
self.discobot_user.username_lower
end
private
def reply_to(post, raw, opts = {}, post_alert_options = {})
defaut_post_alert_opts = { skip_send_email: true }.merge(post_alert_options)
if post
default_opts = {
raw: raw,
topic_id: post.topic_id,
reply_to_post_number: post.post_number,
post_alert_options: defaut_post_alert_opts,
skip_validations: true
}
new_post = PostCreator.create!(self.discobot_user, default_opts.merge(opts))
reset_rate_limits(post) if new_post
new_post
else
PostCreator.create!(self.discobot_user, {
post_alert_options: defaut_post_alert_opts,
raw: raw,
skip_validations: true
}.merge(opts))
end
end
def reset_rate_limits(post)
user = post.user
duration =
if user && user.new_user?
SiteSetting.rate_limit_new_user_create_post
else
SiteSetting.rate_limit_create_post
end
return unless duration > 0
data = DiscourseNarrativeBot::Store.get(user.id.to_s)
return unless data
key = "#{DiscourseNarrativeBot::PLUGIN_NAME}:reset-rate-limit:#{post.topic_id}:#{data['state']}"
if !(count = Discourse.redis.get(key))
count = 0
Discourse.redis.setex(key, duration, count)
end
if count.to_i < 2
post.default_rate_limiter.rollback!
post.limit_posts_per_day&.rollback!
Discourse.redis.incr(key)
end
end
def fake_delay
sleep(rand(2..3)) if Rails.env.production?
end
def bot_mentioned?(post)
doc = Nokogiri::HTML5.fragment(post.cooked)
valid = false
doc.css(".mention").each do |mention|
if User.normalize_username(mention.text) == "@#{self.discobot_username}"
valid = true
break
end
end
valid
end
def reply_to_bot_post?(post)
post&.reply_to_post && post.reply_to_post.user_id == -2
end
def pm_to_bot?(post)
topic = post.topic
return false if !topic
topic.pm_with_non_human_user? &&
topic.topic_allowed_users.where(user_id: -2).exists?
end
def cancel_timeout_job(user)
Jobs.cancel_scheduled_job(:narrative_timeout, user_id: user.id, klass: self.class.to_s)
end
def enqueue_timeout_job(user)
return if Rails.env.test?
cancel_timeout_job(user)
Jobs.enqueue_in(TIMEOUT_DURATION, :narrative_timeout,
user_id: user.id,
klass: self.class.to_s
)
end
end
end