Skip to content

Commit c2c11fd

Browse files
authored
Merge pull request #180 from denis1011101/fix/chat-close-notice-silent
fix: письмо о закрытии чата приходит без звука
2 parents 1dc7146 + 62ebcf1 commit c2c11fd

6 files changed

Lines changed: 24 additions & 15 deletions

File tree

app/jobs/send_telegram_notification_job.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
class SendTelegramNotificationJob < ApplicationJob
22
queue_as :default
33

4-
def perform(chat_id, text, parse_mode: nil)
5-
TelegramNotifier.send_message(chat_id, text, parse_mode: parse_mode)
4+
def perform(chat_id, text, parse_mode: nil, silent: false)
5+
TelegramNotifier.send_message(chat_id, text, parse_mode: parse_mode, silent: silent)
66
rescue => e
77
Rails.logger.warn "SendTelegramNotificationJob failed: #{e.message}"
88
end

app/services/telegram/chat/closure.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,19 @@ def prepare(game, reason, users = nil)
2424
end
2525

2626
# Указатель гасим здесь же: иначе человек останется в чате, которого уже
27-
# нет, и следующее его сообщение уйдёт в никуда. Двумя проходами и с
27+
# нет, и следующее его сообщение уйдёт в никуда. Шлём без звука: чат
28+
# закрывают в четыре утра субботы, и будить этим человека незачем —
29+
# прочитает, когда сам откроет телеграм. Двумя проходами и с
2830
# оговоркой на каждого: сброс состава и удаление игры уже случились,
2931
# второго захода по этим людям не будет — так что одна упавшая отправка
3032
# не должна ни оставить остальных в мёртвом чате, ни съесть их письма.
3133
def deliver(game, notices)
3234
notices.each { |notice| guard(notice) { Session.stop_for(notice.user, game) } }
3335
notices.count do |notice|
3436
guard(notice) do
35-
SendTelegramNotificationJob.perform_later(notice.user.telegram_chat_id.to_s, notice.text)
37+
SendTelegramNotificationJob.perform_later(
38+
notice.user.telegram_chat_id.to_s, notice.text, silent: true
39+
)
3640
end
3741
end
3842
end

app/services/telegram/notifier.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ module Telegram
66
class Notifier
77
TOKEN = ENV["TELEGRAM_BOT_TOKEN"].to_s
88

9-
def self.send_message(chat_id, text, parse_mode: "Markdown", link_preview: false)
9+
# silent: письмо приходит без звука и вибрации — для того, что бот шлёт по
10+
# расписанию среди ночи и что человеку достаточно прочитать утром.
11+
def self.send_message(chat_id, text, parse_mode: "Markdown", link_preview: false, silent: false)
1012
return false if TOKEN.empty? || chat_id.blank?
1113

1214
uri = URI("https://api.telegram.org/bot#{TOKEN}/sendMessage")
1315
payload = { "chat_id" => chat_id.to_s, "text" => text.to_s }
1416
payload["parse_mode"] = parse_mode if parse_mode.present?
1517
payload["link_preview_options"] = Telegram::Api::LINK_PREVIEW_DISABLED unless link_preview
18+
payload["disable_notification"] = "true" if silent
1619
res = Net::HTTP.post_form(uri, payload)
1720
body = JSON.parse(res.body) rescue {}
1821
body["ok"] == true

test/jobs/cleanup_past_one_off_games_job_test.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,15 @@ def setup
8888
game.participations.create!(user: player, status: "approved", approved_at: Time.current)
8989

9090
sent = []
91-
stub_singleton(SendTelegramNotificationJob, :perform_later, ->(chat_id, text) { sent << [ chat_id, text ] }) do
91+
stub_singleton(SendTelegramNotificationJob, :perform_later, ->(chat_id, text, **opts) { sent << [ chat_id, text, opts ] }) do
9292
CleanupPastOneOffGamesJob.perform_now
9393
end
9494

9595
assert_nil Game.find_by(id: game.id)
9696
notice = sent.find { |chat_id, _| chat_id == player.telegram_chat_id.to_s }
9797
assert notice, "участнику удалённой игры должно уйти письмо о закрытии чата"
98-
assert_match "чат", notice.last
99-
assert_no_match(/translation missing/i, notice.last)
98+
assert_match "чат", notice[1]
99+
assert_no_match(/translation missing/i, notice[1])
100+
assert_equal({ silent: true }, notice[2], "письмо о закрытии чата приходит без звука")
100101
end
101102
end

test/jobs/reset_participations_job_test.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class ResetParticipationsJobTest < ActiveJob::TestCase
6262
with_memory_cache do
6363
Telegram::Chat::Session.start(player.telegram_chat_id.to_s, game)
6464

65-
stub_singleton(SendTelegramNotificationJob, :perform_later, ->(chat_id, text) { sent << [ chat_id, text ] }) do
65+
stub_singleton(SendTelegramNotificationJob, :perform_later, ->(chat_id, text, **opts) { sent << [ chat_id, text, opts ] }) do
6666
ResetParticipationsJob.perform_now
6767
end
6868

@@ -71,8 +71,9 @@ class ResetParticipationsJobTest < ActiveJob::TestCase
7171
end
7272

7373
assert_equal [ player.telegram_chat_id.to_s ], sent.map(&:first)
74-
assert_match "закрыт", sent.first.last
75-
assert_no_match(/translation missing/i, sent.first.last)
74+
assert_match "закрыт", sent.first[1]
75+
assert_no_match(/translation missing/i, sent.first[1])
76+
assert_equal({ silent: true }, sent.first[2], "письмо о закрытии чата приходит без звука")
7677
end
7778

7879
# Организатор из состава не выпадает — ему закрывать нечего.
@@ -84,7 +85,7 @@ class ResetParticipationsJobTest < ActiveJob::TestCase
8485

8586
sent = []
8687
with_memory_cache do
87-
stub_singleton(SendTelegramNotificationJob, :perform_later, ->(chat_id, text) { sent << [ chat_id, text ] }) do
88+
stub_singleton(SendTelegramNotificationJob, :perform_later, ->(chat_id, text, **opts) { sent << [ chat_id, text, opts ] }) do
8889
ResetParticipationsJob.perform_now
8990
end
9091
end

test/telegram/chat/closure_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ class Telegram::Chat::ClosureTest < ActiveSupport::TestCase
2929

3030
sent = []
3131
broken = @owner.telegram_chat_id.to_s
32-
stub_singleton(SendTelegramNotificationJob, :perform_later, lambda { |chat_id, _text|
32+
stub_singleton(SendTelegramNotificationJob, :perform_later, lambda { |chat_id, _text, **opts|
3333
raise "telegram is down" if chat_id == broken
3434

35-
sent << chat_id
35+
sent << [ chat_id, opts ]
3636
}) do
3737
assert_equal 1, Telegram::Chat::Closure.notify(@game, :chat_closed_finished)
3838
end
3939

40-
assert_equal [ @player.telegram_chat_id.to_s ], sent
40+
assert_equal [ [ @player.telegram_chat_id.to_s, { silent: true } ] ], sent
4141
assert_nil Telegram::Chat::Session.active_game(@owner.telegram_chat_id.to_s, @owner)
4242
assert_nil Telegram::Chat::Session.active_game(@player.telegram_chat_id.to_s, @player)
4343
end

0 commit comments

Comments
 (0)