Send message fix for `email` cahnnel (#961)

* fix for send_message emails
* Update log filtering rules in log digest delivery mailer
* Cleanup log digest email query, add tests for it
pull/963/head
Rick Carlino 2018-08-16 09:59:38 -05:00 committed by GitHub
parent 1056d8df88
commit 623258c50f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 19 deletions

View File

@ -144,9 +144,6 @@ private
if outcome.success?
render options.merge(json: outcome.result)
else
Rollbar.info("Mutation error",
errors: outcome.errors.message_list.join(" "),
user: current_user.try(:email) || "No User")
render options.merge(json: outcome.errors.message, status: 422)
end
end

View File

@ -1,25 +1,23 @@
class LogDeliveryMailer < ApplicationMailer
WHOAH = "Device %s is sending too many emails!!! (> 20 / hr)"
def maybe_crash_if_too_many_logs(device)
query_params = { sent_at: 1.hours.ago..Time.now, device_id: device.id }
sent_this_hour = Log.where(query_params).count
too_many = sent_this_hour > Log.max_per_hour
raise Log::RateLimitError, WHOAH % [device.id] if too_many
end
def log_digest(device)
Log.transaction do
query_params = { sent_at: 1.hours.ago..Time.now, device_id: device.id }
sent_this_hour = Log.where(query_params).count
too_many = sent_this_hour > Log.max_per_hour
raise Log::RateLimitError, WHOAH % [device.id] if too_many
unsent = Log.where(sent_at: nil, device: device)
maybe_crash_if_too_many_logs(device)
unsent = device.unsent_routine_emails
if(unsent.any?)
logs = Log
.where(id: unsent.pluck(:id))
.where
.not(Log::IS_FATAL_EMAIL)
.order(created_at: :desc)
@emails = device.users.pluck(:email)
@messages = logs
@messages = unsent
.pluck(:created_at, :message)
.map{|(t,m)| [t.in_time_zone(device.timezone || "UTC"), m] }
.map{|(x,y)| "[#{x}]: #{y}"}
.join("\n\n")
@device_name = device.name || "Farmbot"
mail(to: @emails, subject: "🌱 New message from #{@device_name}!")
unsent.update_all(sent_at: Time.now)

View File

@ -160,4 +160,13 @@ class Device < ApplicationRecord
def is_device # SEE: Hack in Log::Create. TODO: Fix low level caching bug.
true
end
def unsent_routine_emails
logs
.where(sent_at: nil)
.where(Log::IS_EMAIL_ISH) # `email` and `fatal_email`
.where
.not(Log::IS_FATAL_EMAIL) # Filter out `fatal_email`s
.order(created_at: :desc)
end
end

View File

@ -11,10 +11,12 @@ class Log < ApplicationRecord
# pagination, but could later on.
PAGE_SIZE = 25
DISCARD = ["fun", "debug", nil]
# self.meta[:type] is used by the bot and the frontend as a sort of
TYPES = CeleryScriptSettingsBag::ALLOWED_MESSAGE_TYPES
# Why "EMAIL_ISH"? Because `fatal_email` is LIKE '%email%', but it's probably
# not the one you want.
IS_EMAIL_ISH = "channels LIKE '%email%'"
IS_FATAL_EMAIL = "channels LIKE '%fatal_email%'"
DISCARD = ["fun", "debug", nil]
TYPES = CeleryScriptSettingsBag::ALLOWED_MESSAGE_TYPES
# The means by which the message will be sent. Ex: frontend toast notification
serialize :channels
belongs_to :device

View File

@ -106,7 +106,7 @@ describe Api::LogsController do
end
it "delivers emails for logs marked as `email`" do
log = Log.create!(device: user.device)
log = Log.create!(device: user.device, channels: ["email"])
b4 = Log.where(sent_at: nil).count
ldm = LogDeliveryMailer.new
allow(ldm).to receive(:mail)

View File

@ -84,4 +84,15 @@ describe Device do
it "is a device" do
expect(Device.new.is_device).to eq(true)
end
it "keeps track of unsent _ROUTINE_ emails" do
πŸ€– = FactoryBot.create(:device)
πŸ“§ = FactoryBot.create(:log, device: πŸ€–, channels: ["email"])
πŸš‘ = FactoryBot.create(:log, device: πŸ€–, channels: ["fatal_email"])
🍞 = FactoryBot.create(:log, device: πŸ€–, channels: ["toast"])
results = πŸ€–.unsent_routine_emails
expect(results).to include(πŸ“§)
expect(results).to_not include(πŸš‘)
expect(results).to_not include(🍞)
end
end