Skip to content

Commit

Permalink
Support updating live calls
Browse files Browse the repository at this point in the history
  • Loading branch information
dwilkie committed Apr 30, 2024
1 parent 0d16dfb commit 74e4ed3
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 47 deletions.
7 changes: 7 additions & 0 deletions components/app/app/jobs/update_call_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class UpdateCallJob
include SuckerPunch::Job

def perform(call_controller)
call_controller.run
end
end
22 changes: 3 additions & 19 deletions components/app/app/models/outbound_call.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,16 @@ def initialize(call_params)
end

def initiate
sip_headers = SIPHeaders.new(
call_sid: call_params.fetch("sid"),
account_sid: call_params.fetch("account_sid")
)

dial_string = DialString.new(call_params.fetch("routing_parameters"))
call_properties = BuildCallProperties.call(call_params)
sip_headers = call_properties.sip_headers

Adhearsion::OutboundCall.originate(
dial_string.to_s,
from: dial_string.format_number(call_params.fetch("from")),
controller: CallController,
controller_metadata: {
call_properties: CallProperties.new(
voice_url: call_params.fetch("voice_url"),
voice_method: call_params.fetch("voice_method"),
twiml: call_params["twiml"],
account_sid: call_params.fetch("account_sid"),
auth_token: call_params.fetch("account_auth_token"),
call_sid: call_params.fetch("sid"),
direction: call_params.fetch("direction"),
api_version: call_params.fetch("api_version"),
from: call_params.fetch("from"),
to: call_params.fetch("to"),
default_tts_voice: call_params.fetch("default_tts_voice"),
sip_headers:
)
call_properties:
},
headers: build_call_headers(sip_headers)
)
Expand Down
12 changes: 12 additions & 0 deletions components/app/app/web/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ class API < Application

status 204
end

patch "/calls/:id" do
call = Adhearsion.active_calls[params[:id]]
return 404 if call.blank?

call_params = JSON.parse(request.body.read)
call_properties = BuildCallProperties.call(call_params)

UpdateCallJob.perform_async(CallController.new(call, call_properties:))

status 204
end
end
end
end
34 changes: 34 additions & 0 deletions components/app/app/workflows/bulid_call_properties.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class BuildCallProperties < ApplicationWorkflow
attr_reader :call_params

def initialize(call_params)
super()
@call_params = call_params
end

def call
CallProperties.new(
voice_url: call_params.fetch("voice_url"),
voice_method: call_params.fetch("voice_method"),
twiml: call_params["twiml"],
account_sid: call_params.fetch("account_sid"),
auth_token: call_params.fetch("account_auth_token"),
call_sid: call_params.fetch("sid"),
direction: call_params.fetch("direction"),
api_version: call_params.fetch("api_version"),
from: call_params.fetch("from"),
to: call_params.fetch("to"),
default_tts_voice: call_params.fetch("default_tts_voice"),
sip_headers:
)
end

private

def sip_headers
@sip_headers ||= SIPHeaders.new(
call_sid: call_params.fetch("sid"),
account_sid: call_params.fetch("account_sid")
)
end
end

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 62 additions & 28 deletions components/app/spec/web/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,44 @@ module Web
it "requires basic authentication" do
basic_authorize "username", "wrong-password"

post "/calls"
post("/calls")

expect(last_response.status).to eq(401)
end

describe "POST /calls" do
it "initiates an outbound call" do
outbound_call = instance_double(Adhearsion::OutboundCall, id: "123456")
call_id = SecureRandom.uuid
outbound_call = instance_double(Adhearsion::OutboundCall, id: call_id)
allow(Adhearsion::OutboundCall).to receive(:originate).and_return(outbound_call)

basic_authorize "adhearsion", "password"
post(
"/calls",
{
"to" => "+85516701721",
"from" => "2442",
"voice_url" => "https://rapidpro.ngrok.com/handle/33/",
"voice_method" => "GET",
"status_callback_url" => "https://rapidpro.ngrok.com/handle/33/",
"status_callback_method" => "POST",
"sid" => "sample-call-sid",
"account_sid" => "sample-account-sid",
"account_auth_token" => "sample-auth-token",
"direction" => "outbound-api",
"api_version" => "2010-04-01",
"default_tts_voice" => "Basic.Kal",
"routing_parameters" => {
"destination" => "85516701721",
"dial_string_prefix" => nil,
"plus_prefix" => false,
"national_dialing" => false,
"host" => "27.109.112.141",
"username" => nil,
"symmetric_latching" => true
}
}.to_json,
build_call_properties.to_json,
{
"CONTENT_TYPE" => "application/json"
}
)

expect(last_response.status).to eq(200)
expect(json_response["id"]).to eq("123456")
expect(json_response["id"]).to eq(call_id)
end
end

describe "DELETE /calls/:id" do
it "ends a call" do
call = Adhearsion::Call.new
allow(call).to receive(:id).and_return("123456")
call_id = SecureRandom.uuid
allow(call).to receive(:id).and_return(call_id)
allow(call).to receive(:hangup)
Adhearsion.active_calls << call

basic_authorize "adhearsion", "password"

delete(
"/calls/123456",
"/calls/#{call_id}",
build_call_properties.to_json,
{
"CONTENT_TYPE" => "application/json"
}
Expand All @@ -74,6 +55,59 @@ module Web
expect(call).to have_received(:hangup)
end
end

describe "PATCH /calls/:id" do
it "Redirect an in progress Call to a new URL", :vcr, cassette: :update_call_with_new_url do
call = Adhearsion::Call.new
call_id = SecureRandom.uuid
allow(call).to receive(:id).and_return(call_id)
allow(call).to receive(:hangup)
Adhearsion.active_calls << call

basic_authorize "adhearsion", "password"

patch(
"/calls/#{call_id}",
build_call_properties(
"voice_url" => "https://demo.twilio.com/docs/voice.xml",
"voice_method" => "GET"
).to_json,
{
"CONTENT_TYPE" => "application/json"
}
)

expect(last_response.status).to eq(204)
expect(call).to have_received(:hangup)
end
end

def build_call_properties(**params)
{
"to" => "+85516701721",
"from" => "2442",
"voice_url" => "https://rapidpro.ngrok.com/handle/33/",
"voice_method" => "GET",
"status_callback_url" => "https://rapidpro.ngrok.com/handle/33/",
"status_callback_method" => "POST",
"sid" => "sample-call-sid",
"account_sid" => "sample-account-sid",
"account_auth_token" => "sample-auth-token",
"direction" => "outbound-api",
"api_version" => "2010-04-01",
"default_tts_voice" => "Basic.Kal",
"routing_parameters" => {
"destination" => "85516701721",
"dial_string_prefix" => nil,
"plus_prefix" => false,
"national_dialing" => false,
"host" => "27.109.112.141",
"username" => nil,
"symmetric_latching" => true
},
**params
}
end
end
end
end

0 comments on commit 74e4ed3

Please sign in to comment.