M config.dhall.sample => config.dhall.sample +1 -0
@@ 39,6 39,7 @@
xep0157 = [
{ var = "support-addresses", value = "xmpp:+14169938000@cheogram.com" }
],
+ notify_admin = "muc_or_user@example.com",
sip_host = "sip.jmp.chat",
plans = [
{
M lib/customer.rb => lib/customer.rb +1 -1
@@ 49,7 49,7 @@ class Customer
def_delegators :@plan, :active?, :activate_plan_starting_now, :bill_plan,
:currency, :merchant_account, :plan_name
def_delegators :@sgx, :register!, :registered?
- def_delegator :@usage, :report, :usage_report
+ def_delegators :@usage, :usage_report, :message_usage, :incr_message_usage
def initialize(
customer_id,
M lib/customer_usage.rb => lib/customer_usage.rb +29 -1
@@ 7,7 7,7 @@ class CustomerUsage
@customer_id = customer_id
end
- def report(range)
+ def usage_report(range)
EMPromise.all([
messages_by_day(range),
minutes_by_day(range)
@@ 16,6 16,34 @@ class CustomerUsage
end
end
+ def expire_message_usage
+ today = Time.now.utc.to_date
+ REDIS.zremrangebylex(
+ "jmp_customer_outbound_messages-#{@customer_id}",
+ "-",
+ # Store message counts per day for 1 year
+ "[#{(today << 12).strftime('%Y%m%d')}"
+ )
+ end
+
+ def incr_message_usage(amount=1)
+ today = Time.now.utc.to_date
+ EMPromise.all([
+ expire_message_usage,
+ REDIS.zincrby(
+ "jmp_customer_outbound_messages-#{@customer_id}",
+ amount,
+ today.strftime("%Y%m%d")
+ )
+ ])
+ end
+
+ def message_usage(range)
+ messages_by_day(range).then do |by_day|
+ by_day.values.sum
+ end
+ end
+
def messages_by_day(range)
EMPromise.all(range.first.downto(range.last).map { |day|
REDIS.zscore(
M sgx_jmp.rb => sgx_jmp.rb +21 -12
@@ 163,28 163,37 @@ before nil, to: /\Acustomer_/, from: /(\A|@)#{CONFIG[:sgx]}(\/|\Z)/ do |s|
halt
end
+# Ignore messages to component
+# Especially if we have the component join MUC for notifications
+message(to: /\A#{CONFIG[:component][:jid]}\Z/) {}
+
message do |m|
sentry_hub = new_sentry_hub(m, name: "message")
+ today = Time.now.utc.to_date
Customer.for_jid(m.from.stripped).then { |customer|
sentry_hub.current_scope.set_user(
id: customer.customer_id,
jid: m.from.stripped.to_s
)
- today = Time.now.utc.to_date
EMPromise.all([
- REDIS.zremrangebylex(
- "jmp_customer_outbound_messages-#{customer.customer_id}",
- "-",
- # Store message counts per day for 1 year
- "[#{(today << 12).strftime('%Y%m%d')}"
- ),
- REDIS.zincrby(
- "jmp_customer_outbound_messages-#{customer.customer_id}",
- 1,
- today.strftime("%Y%m%d")
- ),
+ customer,
+ customer.incr_message_usage,
+ REDIS.exists("jmp_usage_notify-#{customer.customer_id}"),
customer.stanza_from(m)
])
+ }.then { |(customer, _, already, _)|
+ next if already == 1
+
+ customer.message_usage((today..(today - 30))).then do |usage|
+ next unless usage > 500
+
+ BLATHER.join(CONFIG[:notify_admin], "sgx-jmp")
+ BLATHER.say(
+ CONFIG[:notify_admin],
+ "#{customer.customer_id} has used #{usage} messages since #{today - 30}"
+ )
+ REDIS.set("jmp_usage_notify-#{customer.customer_id}", ex: 60 * 60 * 24)
+ end
}.catch { |e| panic(e, sentry_hub) }
end