From a93c39726aed7f20463cc8668167bbf368c454e2 Mon Sep 17 00:00:00 2001 From: Min Zeya Phyo Date: Tue, 28 Jul 2026 02:17:51 +0800 Subject: [PATCH] feat(ntfy): dispatch sms_delivered and sms_failed from SmsMessage --- app/models/sms_message.rb | 25 +++++++++++------- test/models/sms_message_test.rb | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 test/models/sms_message_test.rb diff --git a/app/models/sms_message.rb b/app/models/sms_message.rb index 11a46ca..e3a67ec 100644 --- a/app/models/sms_message.rb +++ b/app/models/sms_message.rb @@ -1,4 +1,6 @@ class SmsMessage < ApplicationRecord + include NtfyDispatchable + # Normalize metadata to always be a Hash attribute :metadata, :jsonb, default: {} @@ -52,19 +54,24 @@ class SmsMessage < ApplicationRecord # Mark message as delivered def mark_delivered! - update!( - status: "delivered", - delivered_at: Time.current - ) + update!(status: "delivered", delivered_at: Time.current) + + self.class.dispatch_ntfy("sms_delivered", + title: "SMS delivered", + message: "Message to #{phone_number} (#{message_id}) was delivered", + priority: 2, + tags: ["white_check_mark"]) end # Mark message as failed def mark_failed!(error_msg = nil) - update!( - status: "failed", - failed_at: Time.current, - error_message: error_msg - ) + update!(status: "failed", failed_at: Time.current, error_message: error_msg) + + self.class.dispatch_ntfy("sms_failed", + title: "SMS failed", + message: "Message to #{phone_number} (#{message_id}) failed#{error_msg ? ": #{error_msg}" : ''}", + priority: 5, + tags: ["x", "rotating_light"]) end # Increment retry counter diff --git a/test/models/sms_message_test.rb b/test/models/sms_message_test.rb new file mode 100644 index 0000000..c6a69c7 --- /dev/null +++ b/test/models/sms_message_test.rb @@ -0,0 +1,46 @@ +require "test_helper" + +class SmsMessageTest < ActiveSupport::TestCase + include ActiveJob::TestHelper + + setup do + ActiveJob::Base.queue_adapter = :test + @admin = AdminUser.create!( + name: "SMS Admin", email: "sms@example.com", + password: "password123", + ntfy_topic: "sms-topic", ntfy_token: "tk_sms", + ntfy_enabled: true, ntfy_server_url: "https://ntfy.example.com" + ) + stub_request(:post, "https://ntfy.example.com/sms-topic").to_return(status: 200) + + @gateway = Gateway.create!( + device_id: "sms-gw", name: "SMS GW", + api_key_digest: "d" * 64, status: "online", + last_heartbeat_at: 1.second.ago + ) + end + + test "mark_delivered! dispatches sms_delivered notification" do + sms = SmsMessage.create!( + direction: "outbound", phone_number: "+14152345678", + message_body: "Hello", status: "sent", + gateway: @gateway, sent_at: 1.minute.ago + ) + + assert_enqueued_jobs 1 do + sms.mark_delivered! + end + end + + test "mark_failed! dispatches sms_failed notification with urgent priority" do + sms = SmsMessage.create!( + direction: "outbound", phone_number: "+14152345678", + message_body: "Hello", status: "sent", + gateway: @gateway, sent_at: 1.minute.ago + ) + + assert_enqueued_jobs 1 do + sms.mark_failed!("Network timeout") + end + end +end