-
-
Notifications
You must be signed in to change notification settings - Fork 1
Add Twilio LCR Option to send call straight to voicemail #147
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a new "Send Straight to Voicemail" feature to the Twilio Live Call Routing integration, allowing calls to bypass team member ringing and go directly to voicemail when enabled. The alert is only routed to the team after the caller leaves a voicemail message.
Key changes:
- New
option_send_straight_to_voicemailboolean option that works in conjunction with the voicemail recording feature - Status callback mechanism added to track call lifecycle events and handle early hangups
- Alert routing is deferred until after voicemail is recorded when this option is enabled
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| config/routes.rb | Adds new call_status POST route to handle Twilio call status callbacks |
| config/locales/en.yml | Adds translation keys for the new "Send Straight to Voicemail" option and help text |
| app/views/pager_tree/integrations/live_call_routing/twilio/v3/_show_options.html.erb | Conditionally displays the new option in the integration details view when voicemail recording is enabled |
| app/views/pager_tree/integrations/live_call_routing/twilio/v3/_form_options.html.erb | Adds form field with Alpine.js reactive visibility that shows/hides based on voicemail recording option |
| app/models/pager_tree/integrations/live_call_routing/twilio/v3.rb | Implements core business logic: option definition, status callback registration, voicemail redirection flow, and alert routing after voicemail is recorded |
| app/controllers/pager_tree/integrations/live_call_routing/twilio/v3_controller.rb | Adds call_status endpoint and deferred processing handler to track call lifecycle events |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| validate :validate_record_emails | ||
|
|
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The model should include a validation to ensure that option_send_straight_to_voicemail can only be set to true when option_record is also true. This dependency is enforced in the UI but not at the model level, which could allow invalid configurations if the model is updated programmatically or through other means. Add a custom validation method to check this constraint.
| validate :validate_record_emails | |
| validate :validate_record_emails | |
| validate :validate_send_straight_to_voicemail_record_dependency | |
| def validate_send_straight_to_voicemail_record_dependency | |
| return unless option_send_straight_to_voicemail | |
| return if option_record | |
| errors.add(:option_send_straight_to_voicemail, "can only be enabled when recording is enabled") | |
| end |
| def adapter_process_call_status_deferred | ||
| call_status = adapter_incoming_request_params.dig("CallStatus") | ||
| adapter_source_log&.sublog("Processing call status #{call_status}") | ||
|
|
||
| if ["completed"].include?(call_status) | ||
| self.adapter_alert = alerts.find_by(thirdparty_id: _thirdparty_id) | ||
|
|
||
| if adapter_alert.present? && adapter_alert.meta["live_call_send_straight_to_voicemail"] == true && !adapter_alert.additional_data.any? { |x| x["label"] == "Voicemail" } | ||
| adapter_alert.logs.create!(message: "Caller hung up without leaving a message. Marking alert as resolved.") | ||
| adapter_alert.resolve!(self, force: true) | ||
| elsif adapter_alert.present? && adapter_alert.meta["live_call_send_straight_to_voicemail"] != true && !adapter_alert.meta["live_call_queue_sid"].present? | ||
| adapter_alert.logs.create!(message: "Caller hungup before being put in a queue. Marking alert as resolved.") | ||
| adapter_alert.resolve!(self, force: true) | ||
| end | ||
| end | ||
| end |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new call_status callback handling logic should have test coverage. Tests should verify: (1) alerts are properly resolved when a caller hangs up without leaving a voicemail in straight-to-voicemail mode, (2) alerts are properly routed when a voicemail is left, and (3) alerts are resolved when callers hang up before being queued in normal mode.
| if adapter_alert.meta["live_call_send_straight_to_voicemail"] == true | ||
| adapter_alert.destination_teams = [selected_team] | ||
| adapter_alert.save! | ||
|
|
||
| adapter_alert.logs.create!(message: "Send caller straight to voicemail (integration option).") | ||
|
|
||
| _twiml.redirect(PagerTree::Integrations::Engine.routes.url_helpers.dropped_live_call_routing_twilio_v3_url(id, thirdparty_id: _thirdparty_id), method: "POST") | ||
|
|
||
| return adapter_controller&.render(xml: _twiml.to_xml) | ||
| end |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new straight-to-voicemail feature should have test coverage. Tests should verify: (1) the option is properly saved and validated, (2) calls are redirected to voicemail without being queued when the option is enabled, (3) alerts are routed only after a voicemail is recorded, and (4) the feature only works when voicemail recording is enabled.
| def call_status | ||
| ::PagerTree::Integrations.deferred_request_class.constantize.perform_later_from_request!(request) | ||
|
|
||
| head :ok | ||
| end |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new call_status controller endpoint should have test coverage. Tests should verify that the endpoint properly queues a deferred request and processes the call status callback correctly.
No description provided.