Class: TwilioClient

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
app/services/twilio_client.rb

Overview

Service object: twilio client.

Delegated Instance Attributes collapse

Instance Attribute Summary collapse

Delegated Instance Attributes collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ TwilioClient

Returns a new instance of TwilioClient.



16
17
18
19
20
21
22
23
24
25
26
# File 'app/services/twilio_client.rb', line 16

def initialize(options = {})
  @logger = options[:logger] || Rails.logger
   = options[:account_sid] || Heatwave::Configuration.fetch(:twilio, :account_sid)
  auth_token = options[:auth_token] || Heatwave::Configuration.fetch(:twilio, :auth_token)
  @account_sid = 
  @auth_token = auth_token
  @sms_status_callback_url = options[:sms_status_callback_url]
  @sms_status_callback_url ||= "#{Heatwave::Configuration.fetch(:twilio, :sms_base_wehook_url)}/update_status"
  @default_sender = options[:default_sender] || '+18008755285'
  @client = Twilio::REST::Client.new , auth_token
end

Instance Attribute Details

#clientObject (readonly)

Alias for Instance#client

Returns:

  • (Object)

    Instance#client

See Also:



10
11
12
# File 'app/services/twilio_client.rb', line 10

def client
  @client
end

#default_senderObject (readonly)

Returns the value of attribute default_sender.



10
11
12
# File 'app/services/twilio_client.rb', line 10

def default_sender
  @default_sender
end

#loggerObject (readonly)

Returns the value of attribute logger.



10
11
12
# File 'app/services/twilio_client.rb', line 10

def logger
  @logger
end

Instance Method Details

#delete_recording(recording_sid) ⇒ Object

Delete a recording from Twilio (after successful import)

Parameters:

  • recording_sid (String)

    The Recording SID



182
183
184
185
186
187
188
189
# File 'app/services/twilio_client.rb', line 182

def delete_recording(recording_sid)
  client.recordings(recording_sid).delete
  logger.info "[TwilioClient] Deleted recording #{recording_sid}"
  true
rescue Twilio::REST::RestError => e
  logger.error "[TwilioClient] Failed to delete recording #{recording_sid}: #{e.message}"
  false
end

#download_recording(recording_sid, dual_channel: true) ⇒ String

Download a recording as WAV (required when call recording encryption is enabled)
SIP trunk recordings are natively stereo (2 channels) - preserved in WAV format

Note: Twilio error 16109 - When call recording encryption is enabled,
recordings can ONLY be downloaded in WAV format, not MP3.
See: https://www.twilio.com/docs/errors/16109

Parameters:

  • recording_sid (String)

    The Recording SID

  • dual_channel (Boolean) (defaults to: true)

    Ignored - kept for backwards compatibility

Returns:

  • (String)

    Local file path to downloaded recording



150
# File 'app/services/twilio_client.rb', line 150

delegate :client, :send_message, :list_numbers, :list_recordings, :download_recording, :lookup_line_type, to: :instance

#get_call(call_sid) ⇒ Hash

Get call details for a recording (to extract phone numbers)

Parameters:

  • call_sid (String)

    The Twilio Call SID

Returns:

  • (Hash)

    Call metadata including from/to numbers



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'app/services/twilio_client.rb', line 121

def get_call(call_sid)
  call = client.calls(call_sid).fetch
  {
    sid: call.sid,
    from: call.from,
    to: call.to,
    direction: call.direction,
    duration: call.duration.to_i,
    start_time: call.start_time,
    end_time: call.end_time,
    status: call.status,
    # SIP trunk info if available
    trunk_sid: call.trunk_sid
  }
rescue Twilio::REST::RestError => e
  logger.error "[TwilioClient] Failed to fetch call #{call_sid}: #{e.message}"
  nil
end

#list_numbersObject

Alias for Instance#list_numbers

Returns:

  • (Object)

    Instance#list_numbers

See Also:



13
# File 'app/services/twilio_client.rb', line 13

delegate :client, :send_message, :list_numbers, :list_recordings, :download_recording, :lookup_line_type, to: :instance

#list_recordings(date_created_after: nil, limit: 100) ⇒ Array<Hash>

List recordings from Twilio

Parameters:

  • date_created_after (Time) (defaults to: nil)

    Filter recordings created after this time

  • limit (Integer) (defaults to: 100)

    Maximum number of recordings to return

Returns:

  • (Array<Hash>)

    Array of recording metadata



96
# File 'app/services/twilio_client.rb', line 96

delegate :client, :send_message, :list_numbers, :list_recordings, :download_recording, :lookup_line_type, to: :instance

#lookup_line_type(number) ⇒ Symbol

Note:

Logs only the last 4 digits of the number to avoid PII leakage to
centralized log aggregators.

Twilio Lookups v2 Line Type Intelligence.

Returns the carrier-reported line type for an E.164 number, or :unknown
when Twilio can't classify or the lookup fails. Billed per call
(~$0.005 USD as of 2026), so callers should cache by number and re-verify
infrequently.

Logic Details

Twilio's type field is camelCase (fixedVoip, nonFixedVoip,
tollFree, sharedCost); this method normalizes to underscored Ruby
symbols.

Twilio::REST::TwilioError is the parent of both RestError (HTTP 4xx/5xx
responses) and the network/timeout wrappers, so rescuing it preserves the
"always returns :unknown on failure" contract for both flavors of failure.

Parameters:

  • number (String)

    E.164-formatted phone number, e.g. "+15146777418"

Returns:

  • (Symbol)

    one of :mobile, :landline, :fixed_voip,
    :non_fixed_voip, :personal, :toll_free, :premium,
    :shared_cost, :uan, :voicemail, :pager, :unknown

See Also:



76
# File 'app/services/twilio_client.rb', line 76

delegate :client, :send_message, :list_numbers, :list_recordings, :download_recording, :lookup_line_type, to: :instance

#send_message(to:, body:, from: nil, media_urls: nil) ⇒ Object

============================================================================
SMS Methods



32
# File 'app/services/twilio_client.rb', line 32

delegate :client, :send_message, :list_numbers, :list_recordings, :download_recording, :lookup_line_type, to: :instance