## Description Agents can now place a WhatsApp call to a contact straight from the contacts screen, even if that contact has never messaged in. Previously the call only worked once a conversation already existed, so a freshly added contact would fail with "Unable to start the call. Please try again." — the only workaround was to get the contact to message the channel first. ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Manually via UI ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
33 lines
1.3 KiB
Ruby
33 lines
1.3 KiB
Ruby
class Whatsapp::CallConversationBuilder
|
|
pattr_initialize [:inbox!, :contact!, :user!]
|
|
|
|
# Mirrors the continuity rule in Whatsapp::IncomingMessageBaseService#set_conversation.
|
|
# Locked inboxes hold a contact to one thread, so the caller is refused rather than given a second one.
|
|
def existing_conversation
|
|
return contact_conversations.first if inbox.lock_to_single_conversation
|
|
|
|
# Only threads the caller can open, else a newest-but-hidden thread would block the call.
|
|
Conversations::PermissionFilterService.new(
|
|
contact_conversations.where.not(status: :resolved), user, inbox.account
|
|
).perform.first
|
|
end
|
|
|
|
def contact_conversations
|
|
inbox.conversations.where(contact_id: contact.id).order(last_activity_at: :desc)
|
|
end
|
|
|
|
# Unsaved, so callers can authorize the thread a call would open before dialing.
|
|
def new_conversation
|
|
inbox.account.conversations.new(inbox: inbox, contact: contact, assignee_id: user.id, status: :open)
|
|
end
|
|
|
|
# Locked so two agents calling the same fresh contact can't open two threads.
|
|
def perform!
|
|
contact_inbox = ContactInboxBuilder.new(contact: contact, inbox: inbox).perform
|
|
|
|
contact_inbox.with_lock do
|
|
existing_conversation || new_conversation.tap { |conversation| conversation.update!(contact_inbox: contact_inbox) }
|
|
end
|
|
end
|
|
end
|