feat: Notification on new messages in conversation (#1204)

fixes: #895
fixes: #1118
fixes: #1075

Co-authored-by: Pranav Raj S <pranav@thoughtwoot.com>
This commit is contained in:
Sojan Jose
2020-09-10 19:19:15 +05:30
committed by GitHub
co-authored by Pranav Raj S
parent 3b92c744d6
commit 31c07771e8
36 changed files with 259 additions and 94 deletions
+2 -2
View File
@@ -5,10 +5,10 @@
# id :integer not null, primary key
# additional_attributes :jsonb
# agent_last_seen_at :datetime
# contact_last_seen_at :datetime
# identifier :string
# locked :boolean default(FALSE)
# status :integer default("open"), not null
# user_last_seen_at :datetime
# uuid :uuid not null
# created_at :datetime not null
# updated_at :datetime not null
@@ -166,7 +166,7 @@ class Conversation < ApplicationRecord
{
CONVERSATION_OPENED => -> { saved_change_to_status? && open? },
CONVERSATION_RESOLVED => -> { saved_change_to_status? && resolved? },
CONVERSATION_READ => -> { saved_change_to_user_last_seen_at? },
CONVERSATION_READ => -> { saved_change_to_contact_last_seen_at? },
CONVERSATION_LOCK_TOGGLE => -> { saved_change_to_locked? },
ASSIGNEE_CHANGED => -> { saved_change_to_assignee_id? },
CONVERSATION_CONTACT_CHANGED => -> { saved_change_to_contact_id? }
+21 -7
View File
@@ -150,14 +150,28 @@ class Message < ApplicationRecord
::MessageTemplates::HookExecutionService.new(message: self).perform
end
def notify_via_mail
if Redis::Alfred.get(conversation_mail_key).nil? && conversation.contact.email? && outgoing? && !private
# set a redis key for the conversation so that we don't need to send email for every
# new message that comes in and we dont enque the delayed sidekiq job for every message
Redis::Alfred.setex(conversation_mail_key, Time.zone.now)
def email_notifiable_message?
return false unless outgoing?
return false if private?
# Since this is live chat, send the email after few minutes so the only one email with
# last few messages coupled together is sent rather than email for each message
true
end
def can_notify_via_mail?
return unless email_notifiable_message?
return false if conversation.contact.email.blank?
return false unless %w[Website Email].include? inbox.inbox_type
true
end
def notify_via_mail
return unless can_notify_via_mail?
# set a redis key for the conversation so that we don't need to send email for every new message
# last few messages coupled together is sent every 2 minutes rather than one email for each message
if Redis::Alfred.get(conversation_mail_key).nil?
Redis::Alfred.setex(conversation_mail_key, Time.zone.now)
ConversationReplyEmailWorker.perform_in(2.minutes, conversation.id, Time.zone.now)
end
end
+5 -1
View File
@@ -31,7 +31,8 @@ class Notification < ApplicationRecord
NOTIFICATION_TYPES = {
conversation_creation: 1,
conversation_assignment: 2
conversation_assignment: 2,
assigned_conversation_new_message: 3
}.freeze
enum notification_type: NOTIFICATION_TYPES
@@ -64,6 +65,8 @@ class Notification < ApplicationRecord
return "A new conversation [ID -#{primary_actor.display_id}] has been assigned to you." if notification_type == 'conversation_assignment'
return "New message in your assigned conversation [ID -#{primary_actor.display_id}]." if notification_type == 'assigned_conversation_new_message'
''
end
@@ -71,6 +74,7 @@ class Notification < ApplicationRecord
def process_notification_delivery
Notification::PushNotificationJob.perform_later(self)
# Should we do something about the case where user subscribed to both push and email ?
# In future, we could probably add condition here to enqueue the job for 30 seconds later
# when push enabled and then check in email job whether notification has been read already.