Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce idea of tracking received/read messages #1702

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/adapters/signal_adapter/inbound.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module SignalAdapter
UNKNOWN_CONTRIBUTOR = :unknown_contributor
UNKNOWN_CONTENT = :unknown_content
CONNECT = :connect
HANDLE_DELIVERY_RECEIPT = :handle_delivery_receipt

class Inbound
UNKNOWN_CONTENT_KEYS = %w[mentions contacts sticker].freeze
Expand Down Expand Up @@ -66,6 +67,8 @@ def initialize_sender(signal_message)
def initialize_message(signal_message)
is_data_message = signal_message.dig(:envelope, :dataMessage)
is_remove_emoji = signal_message.dig(:envelope, :dataMessage, :reaction, :isRemove)
is_delivery_receipt = signal_message.dig(:envelope, :receiptMessage)
trigger(HANDLE_DELIVERY_RECEIPT, is_delivery_receipt, sender) if is_delivery_receipt
return nil if !is_data_message || is_remove_emoji

data_message = signal_message.dig(:envelope, :dataMessage)
Expand Down
2 changes: 1 addition & 1 deletion app/components/checkbox/checkbox.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
<%= checked ? 'checked' : '' %>
<%= required ? 'required' : '' %>
<%= attrs %>
/>
/>
21 changes: 18 additions & 3 deletions app/jobs/signal_adapter/receive_polling_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ def perform(*_args)
adapter = SignalAdapter::Inbound.new

adapter.on(SignalAdapter::CONNECT) do |contributor|
contributor.update!(signal_onboarding_completed_at: Time.zone.now)
SignalAdapter::Outbound.send_welcome_message!(contributor)
SignalAdapter::AttachContributorsAvatarJob.perform_later(contributor)
handle_connect(contributor)
end

adapter.on(SignalAdapter::UNKNOWN_CONTRIBUTOR) do |signal_phone_number|
Expand All @@ -31,6 +29,10 @@ def perform(*_args)
SignalAdapter::Outbound.send_unknown_content_message!(contributor)
end

adapter.on(SignalAdapter::HANDLE_DELIVERY_RECEIPT) do |delivery_receipt, contributor|
handle_delivery_receipt(delivery_receipt, contributor)
end

signal_messages.each do |raw_message|
adapter.consume(raw_message) { |m| m.contributor.reply(adapter) }
rescue StandardError => e
Expand Down Expand Up @@ -60,5 +62,18 @@ def ping_monitoring_service
def queue_empty?
Delayed::Job.where(queue: queue_name, failed_at: nil).none?
end

def handle_connect(contributor)
contributor.update!(signal_onboarding_completed_at: Time.zone.now)
SignalAdapter::Outbound.send_welcome_message!(contributor)
SignalAdapter::AttachContributorsAvatarJob.perform_later(contributor)
end

def handle_delivery_receipt(delivery_receipt, contributor)
datetime = Time.zone.at(delivery_receipt[:when] / 1000).to_datetime
latest_received_message = contributor.received_messages.first
latest_received_message.update(received_at: datetime) if delivery_receipt[:isDelivery]
latest_received_message.update(read_at: datetime) if delivery_receipt[:isRead]
end
end
end
7 changes: 7 additions & 0 deletions db/migrate/20230915070544_add_received_at_to_messages.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddReceivedAtToMessages < ActiveRecord::Migration[6.1]
def change
add_column :messages, :received_at, :datetime, default: nil
end
end
7 changes: 7 additions & 0 deletions db/migrate/20231024144124_add_read_at_to_messages.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddReadAtToMessages < ActiveRecord::Migration[6.1]
def change
add_column :messages, :read_at, :datetime, default: nil
end
end
4 changes: 3 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2023_06_30_061952) do
ActiveRecord::Schema.define(version: 2023_10_24_144124) do

# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
Expand Down Expand Up @@ -169,6 +169,8 @@
t.boolean "highlighted", default: false
t.bigint "creator_id"
t.string "sender_type"
t.datetime "received_at"
t.datetime "read_at"
t.index ["creator_id"], name: "index_messages_on_creator_id"
t.index ["recipient_id"], name: "index_messages_on_recipient_id"
t.index ["request_id"], name: "index_messages_on_request_id"
Expand Down
36 changes: 30 additions & 6 deletions spec/adapters/signal_adapter/inbound_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@
{
envelope: {
source: '+4912345789',
sourceNumber: '+4912345789',
sourceUuid: 'valid_uuid',
sourceName: 'Signal Contributor',
sourceDevice: 1,
timestamp: 1_626_711_330_462,
timestamp: 1_694_759_894_782,
receiptMessage: {
when: 1_626_711_330_462,
when: 1_694_759_894_782,
isDelivery: true,
isRead: false,
timestamps: [
1_626_711_326_111
]
isViewed: false,
timestamps: [1_694_759_894_066]
}
}
},
account: Setting.signal_server_phone_number
}
end

Expand Down Expand Up @@ -205,6 +208,7 @@
end

context 'given a receipt message' do
before { create(:message, recipient_id: contributor.id) }
let(:signal_message) { signal_receipt_message }

it { should be(nil) }
Expand Down Expand Up @@ -454,5 +458,25 @@
it { should have_received(:call).with(contributor) }
end
end

describe 'HANDLE_DELIVERY_RECEIPT' do
let(:handle_delivery_receipt_callback) { spy('handle_delivery_receipt_callback') }
let(:signal_message) { signal_receipt_message }

before do
adapter.on(SignalAdapter::HANDLE_DELIVERY_RECEIPT) do |delivery_receipt, contributor|
handle_delivery_receipt_callback.call(delivery_receipt, contributor)
end
end

subject do
adapter.consume(signal_message)
handle_delivery_receipt_callback
end

describe 'if the message is a delivery receipt' do
it { should have_received(:call) }
end
end
end
end