retell-sdk-unofficial 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/retell/sdk/unofficial/agent.rb +73 -0
- data/lib/retell/sdk/unofficial/agent_list.rb +11 -0
- data/lib/retell/sdk/unofficial/api/agent.rb +348 -0
- data/lib/retell/sdk/unofficial/api/call.rb +212 -0
- data/lib/retell/sdk/unofficial/api/concurrency.rb +28 -0
- data/lib/retell/sdk/unofficial/api/phone_number.rb +179 -0
- data/lib/retell/sdk/unofficial/api/retell_llm.rb +254 -0
- data/lib/retell/sdk/unofficial/api/voice.rb +50 -0
- data/lib/retell/sdk/unofficial/base.rb +81 -0
- data/lib/retell/sdk/unofficial/base_call.rb +40 -0
- data/lib/retell/sdk/unofficial/base_list.rb +52 -0
- data/lib/retell/sdk/unofficial/call.rb +18 -0
- data/lib/retell/sdk/unofficial/call_list.rb +14 -0
- data/lib/retell/sdk/unofficial/client.rb +285 -0
- data/lib/retell/sdk/unofficial/concurrency.rb +17 -0
- data/lib/retell/sdk/unofficial/phone_call.rb +22 -0
- data/lib/retell/sdk/unofficial/phone_number.rb +62 -0
- data/lib/retell/sdk/unofficial/phone_number_list.rb +11 -0
- data/lib/retell/sdk/unofficial/retell_llm.rb +59 -0
- data/lib/retell/sdk/unofficial/retell_llm_list.rb +11 -0
- data/lib/retell/sdk/unofficial/version.rb +7 -0
- data/lib/retell/sdk/unofficial/voice.rb +25 -0
- data/lib/retell/sdk/unofficial/voice_list.rb +11 -0
- data/lib/retell/sdk/unofficial/web_call.rb +20 -0
- data/lib/retell/sdk/unofficial.rb +33 -0
- metadata +142 -0
@@ -0,0 +1,179 @@
|
|
1
|
+
module Retell
|
2
|
+
module SDK
|
3
|
+
module Unofficial
|
4
|
+
module API
|
5
|
+
class PhoneNumber
|
6
|
+
def initialize(client)
|
7
|
+
@client = client
|
8
|
+
end
|
9
|
+
|
10
|
+
def create(
|
11
|
+
area_code: nil,
|
12
|
+
inbound_agent_id: nil,
|
13
|
+
inbound_agent: nil,
|
14
|
+
nickname: nil,
|
15
|
+
outbound_agent_id: nil,
|
16
|
+
outbound_agent: nil,
|
17
|
+
extra_headers: nil,
|
18
|
+
extra_query: nil,
|
19
|
+
extra_body: nil,
|
20
|
+
timeout: nil
|
21
|
+
)
|
22
|
+
inbound_agent_id = inbound_agent_id || inbound_agent
|
23
|
+
outbound_agent_id = outbound_agent_id || outbound_agent
|
24
|
+
|
25
|
+
inbound_agent_id = inbound_agent_id.is_a?(Retell::SDK::Unofficial::Agent) ? inbound_agent_id.agent_id : inbound_agent_id
|
26
|
+
outbound_agent_id = outbound_agent_id.is_a?(Retell::SDK::Unofficial::Agent) ? outbound_agent_id.agent_id : outbound_agent_id
|
27
|
+
|
28
|
+
payload = {
|
29
|
+
area_code: area_code,
|
30
|
+
inbound_agent_id: inbound_agent_id,
|
31
|
+
nickname: nickname,
|
32
|
+
outbound_agent_id: outbound_agent_id
|
33
|
+
}.compact
|
34
|
+
|
35
|
+
options = @client.make_request_options(
|
36
|
+
extra_headers: extra_headers,
|
37
|
+
extra_query: extra_query,
|
38
|
+
extra_body: extra_body,
|
39
|
+
timeout: timeout
|
40
|
+
)
|
41
|
+
|
42
|
+
@client.post('/create-phone-number', payload, **options)
|
43
|
+
end
|
44
|
+
|
45
|
+
def import(
|
46
|
+
phone_number,
|
47
|
+
termination_uri:,
|
48
|
+
inbound_agent_id: nil,
|
49
|
+
inbound_agent: nil,
|
50
|
+
nickname: nil,
|
51
|
+
outbound_agent_id: nil,
|
52
|
+
outbound_agent: nil,
|
53
|
+
sip_trunk_auth_password: nil,
|
54
|
+
sip_trunk_auth_username: nil,
|
55
|
+
extra_headers: nil,
|
56
|
+
extra_query: nil,
|
57
|
+
extra_body: nil,
|
58
|
+
timeout: nil
|
59
|
+
)
|
60
|
+
inbound_agent_id = inbound_agent_id || inbound_agent
|
61
|
+
outbound_agent_id = outbound_agent_id || outbound_agent
|
62
|
+
|
63
|
+
inbound_agent_id = inbound_agent_id.is_a?(Retell::SDK::Unofficial::Agent) ? inbound_agent_id.agent_id : inbound_agent_id
|
64
|
+
outbound_agent_id = outbound_agent_id.is_a?(Retell::SDK::Unofficial::Agent) ? outbound_agent_id.agent_id : outbound_agent_id
|
65
|
+
|
66
|
+
payload = {
|
67
|
+
phone_number: phone_number,
|
68
|
+
termination_uri: termination_uri,
|
69
|
+
inbound_agent_id: inbound_agent_id,
|
70
|
+
nickname: nickname,
|
71
|
+
outbound_agent_id: outbound_agent_id,
|
72
|
+
sip_trunk_auth_password: sip_trunk_auth_password,
|
73
|
+
sip_trunk_auth_username: sip_trunk_auth_username
|
74
|
+
}.compact
|
75
|
+
|
76
|
+
options = @client.make_request_options(
|
77
|
+
extra_headers: extra_headers,
|
78
|
+
extra_query: extra_query,
|
79
|
+
extra_body: extra_body,
|
80
|
+
timeout: timeout
|
81
|
+
)
|
82
|
+
|
83
|
+
@client.post('/import-phone-number', payload, **options)
|
84
|
+
end
|
85
|
+
|
86
|
+
def retrieve(
|
87
|
+
phone_number,
|
88
|
+
extra_headers: nil,
|
89
|
+
extra_query: nil,
|
90
|
+
extra_body: nil,
|
91
|
+
timeout: nil
|
92
|
+
)
|
93
|
+
phone_number = phone_number.is_a?(Retell::SDK::Unofficial::PhoneNumber) ? phone_number.phone_number : phone_number
|
94
|
+
|
95
|
+
options = @client.make_request_options(
|
96
|
+
extra_headers: extra_headers,
|
97
|
+
extra_query: extra_query,
|
98
|
+
extra_body: extra_body,
|
99
|
+
timeout: timeout
|
100
|
+
)
|
101
|
+
|
102
|
+
@client.get("/get-phone-number/#{phone_number}", **options)
|
103
|
+
end
|
104
|
+
|
105
|
+
def list(extra_headers: nil, extra_query: nil, extra_body: nil, timeout: nil)
|
106
|
+
options = @client.make_request_options(
|
107
|
+
extra_headers: extra_headers,
|
108
|
+
extra_query: extra_query,
|
109
|
+
extra_body: extra_body,
|
110
|
+
timeout: timeout
|
111
|
+
)
|
112
|
+
|
113
|
+
@client.get('/list-phone-numbers', **options)
|
114
|
+
end
|
115
|
+
|
116
|
+
def update(
|
117
|
+
phone_number,
|
118
|
+
inbound_agent_id: nil,
|
119
|
+
inbound_agent: nil,
|
120
|
+
nickname: nil,
|
121
|
+
outbound_agent_id: nil,
|
122
|
+
outbound_agent: nil,
|
123
|
+
extra_headers: nil,
|
124
|
+
extra_query: nil,
|
125
|
+
extra_body: nil,
|
126
|
+
timeout: nil
|
127
|
+
)
|
128
|
+
inbound_agent_id = inbound_agent_id || inbound_agent
|
129
|
+
outbound_agent_id = outbound_agent_id || outbound_agent
|
130
|
+
|
131
|
+
phone_number = phone_number.is_a?(Retell::SDK::Unofficial::PhoneNumber) ? phone_number.phone_number : phone_number
|
132
|
+
inbound_agent_id = inbound_agent_id.is_a?(Retell::SDK::Unofficial::Agent) ? inbound_agent_id.agent_id : inbound_agent_id
|
133
|
+
outbound_agent_id = outbound_agent_id.is_a?(Retell::SDK::Unofficial::Agent) ? outbound_agent_id.agent_id : outbound_agent_id
|
134
|
+
|
135
|
+
payload = {
|
136
|
+
inbound_agent_id: inbound_agent_id,
|
137
|
+
nickname: nickname,
|
138
|
+
outbound_agent_id: outbound_agent_id
|
139
|
+
}.compact
|
140
|
+
|
141
|
+
options = @client.make_request_options(
|
142
|
+
extra_headers: extra_headers,
|
143
|
+
extra_query: extra_query,
|
144
|
+
extra_body: extra_body,
|
145
|
+
timeout: timeout
|
146
|
+
)
|
147
|
+
|
148
|
+
@client.patch("/update-phone-number/#{phone_number}", payload, **options)
|
149
|
+
end
|
150
|
+
|
151
|
+
def delete(
|
152
|
+
phone_number,
|
153
|
+
extra_headers: nil,
|
154
|
+
extra_query: nil,
|
155
|
+
extra_body: nil,
|
156
|
+
timeout: nil
|
157
|
+
)
|
158
|
+
phone_number = phone_number.is_a?(Retell::SDK::Unofficial::PhoneNumber) ? phone_number.phone_number : phone_number
|
159
|
+
|
160
|
+
options = @client.make_request_options(
|
161
|
+
extra_headers: extra_headers,
|
162
|
+
extra_query: extra_query,
|
163
|
+
extra_body: extra_body,
|
164
|
+
timeout: timeout
|
165
|
+
)
|
166
|
+
|
167
|
+
@client.delete("/delete-phone-number/#{phone_number}", **options)
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
|
172
|
+
def validate_phone_number(value, param_name)
|
173
|
+
raise ArgumentError, "#{param_name} must be a valid phone number in E.164 format" unless value.match?(/^\+[1-9]\d{1,14}$/)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
module Retell
|
2
|
+
module SDK
|
3
|
+
module Unofficial
|
4
|
+
module API
|
5
|
+
class RetellLLM
|
6
|
+
def initialize(client)
|
7
|
+
@client = client
|
8
|
+
end
|
9
|
+
|
10
|
+
def create(
|
11
|
+
begin_message: nil,
|
12
|
+
general_prompt: nil,
|
13
|
+
general_tools: nil,
|
14
|
+
inbound_dynamic_variables_webhook_url: nil,
|
15
|
+
model: nil,
|
16
|
+
model_temperature: nil,
|
17
|
+
starting_state: nil,
|
18
|
+
states: nil,
|
19
|
+
extra_headers: nil,
|
20
|
+
extra_query: nil,
|
21
|
+
extra_body: nil,
|
22
|
+
timeout: nil
|
23
|
+
)
|
24
|
+
validate_model(model) if model
|
25
|
+
validate_model_temperature(model_temperature) if model_temperature
|
26
|
+
validate_general_tools(general_tools) if general_tools
|
27
|
+
validate_states(states) if states
|
28
|
+
|
29
|
+
payload = {
|
30
|
+
begin_message: begin_message,
|
31
|
+
general_prompt: general_prompt,
|
32
|
+
general_tools: general_tools,
|
33
|
+
inbound_dynamic_variables_webhook_url: inbound_dynamic_variables_webhook_url,
|
34
|
+
model: model,
|
35
|
+
model_temperature: model_temperature,
|
36
|
+
starting_state: starting_state,
|
37
|
+
states: states
|
38
|
+
}.compact
|
39
|
+
|
40
|
+
options = @client.make_request_options(
|
41
|
+
extra_headers: extra_headers,
|
42
|
+
extra_query: extra_query,
|
43
|
+
extra_body: extra_body,
|
44
|
+
timeout: timeout
|
45
|
+
)
|
46
|
+
|
47
|
+
@client.post('/create-retell-llm', payload, **options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def retrieve(
|
51
|
+
llm_or_id,
|
52
|
+
extra_headers: nil,
|
53
|
+
extra_query: nil,
|
54
|
+
extra_body: nil,
|
55
|
+
timeout: nil
|
56
|
+
)
|
57
|
+
llm_id = llm_or_id.is_a?(Retell::SDK::Unofficial::RetellLLM) ? llm_or_id.llm_id : llm_or_id
|
58
|
+
validate_non_empty_string(llm_id, 'llm_id')
|
59
|
+
|
60
|
+
options = @client.make_request_options(
|
61
|
+
extra_headers: extra_headers,
|
62
|
+
extra_query: extra_query,
|
63
|
+
extra_body: extra_body,
|
64
|
+
timeout: timeout
|
65
|
+
)
|
66
|
+
|
67
|
+
@client.get("/get-retell-llm/#{llm_id}", **options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def update(
|
71
|
+
llm_or_id,
|
72
|
+
begin_message: nil,
|
73
|
+
general_prompt: nil,
|
74
|
+
general_tools: nil,
|
75
|
+
inbound_dynamic_variables_webhook_url: nil,
|
76
|
+
model: nil,
|
77
|
+
model_temperature: nil,
|
78
|
+
starting_state: nil,
|
79
|
+
states: nil,
|
80
|
+
extra_headers: nil,
|
81
|
+
extra_query: nil,
|
82
|
+
extra_body: nil,
|
83
|
+
timeout: nil
|
84
|
+
)
|
85
|
+
llm_id = llm_or_id.is_a?(Retell::SDK::Unofficial::RetellLLM) ? llm_or_id.llm_id : llm_or_id
|
86
|
+
validate_non_empty_string(llm_id, 'llm_id')
|
87
|
+
|
88
|
+
validate_model(model) if model
|
89
|
+
validate_model_temperature(model_temperature) if model_temperature
|
90
|
+
validate_general_tools(general_tools) if general_tools
|
91
|
+
validate_states(states) if states
|
92
|
+
|
93
|
+
payload = {
|
94
|
+
begin_message: begin_message,
|
95
|
+
general_prompt: general_prompt,
|
96
|
+
general_tools: general_tools,
|
97
|
+
inbound_dynamic_variables_webhook_url: inbound_dynamic_variables_webhook_url,
|
98
|
+
model: model,
|
99
|
+
model_temperature: model_temperature,
|
100
|
+
starting_state: starting_state,
|
101
|
+
states: states
|
102
|
+
}.compact
|
103
|
+
|
104
|
+
options = @client.make_request_options(
|
105
|
+
extra_headers: extra_headers,
|
106
|
+
extra_query: extra_query,
|
107
|
+
extra_body: extra_body,
|
108
|
+
timeout: timeout
|
109
|
+
)
|
110
|
+
|
111
|
+
@client.patch("/update-retell-llm/#{llm_id}", payload, **options)
|
112
|
+
end
|
113
|
+
|
114
|
+
def list(
|
115
|
+
extra_headers: nil,
|
116
|
+
extra_query: nil,
|
117
|
+
extra_body: nil,
|
118
|
+
timeout: nil
|
119
|
+
)
|
120
|
+
options = @client.make_request_options(
|
121
|
+
extra_headers: extra_headers,
|
122
|
+
extra_query: extra_query,
|
123
|
+
extra_body: extra_body,
|
124
|
+
timeout: timeout
|
125
|
+
)
|
126
|
+
|
127
|
+
@client.get('/list-retell-llms', **options)
|
128
|
+
end
|
129
|
+
|
130
|
+
def delete(
|
131
|
+
llm_or_id,
|
132
|
+
extra_headers: nil,
|
133
|
+
extra_query: nil,
|
134
|
+
extra_body: nil,
|
135
|
+
timeout: nil
|
136
|
+
)
|
137
|
+
llm_id = llm_or_id.is_a?(Retell::SDK::Unofficial::RetellLLM) ? llm_or_id.llm_id : llm_or_id
|
138
|
+
validate_non_empty_string(llm_id, 'llm_id')
|
139
|
+
|
140
|
+
options = @client.make_request_options(
|
141
|
+
extra_headers: extra_headers,
|
142
|
+
extra_query: extra_query,
|
143
|
+
extra_body: extra_body,
|
144
|
+
timeout: timeout
|
145
|
+
)
|
146
|
+
|
147
|
+
@client.delete("/delete-retell-llm/#{llm_id}", **options)
|
148
|
+
nil
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def validate_model(model)
|
154
|
+
valid_models = ['gpt-4o', 'gpt-4o-mini', 'claude-3.5-sonnet', 'claude-3-haiku']
|
155
|
+
unless valid_models.include?(model)
|
156
|
+
raise ArgumentError, "Invalid model: #{model}. Valid models are: #{valid_models.join(', ')}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def validate_model_temperature(model_temperature)
|
161
|
+
unless model_temperature >= 0 && model_temperature <= 1
|
162
|
+
raise ArgumentError, "Invalid model temperature: #{model_temperature}. Model temperature must be a between 0 and 1"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def validate_general_tools(tools)
|
167
|
+
tools.each { |tool| validate_general_tool(tool) }
|
168
|
+
end
|
169
|
+
|
170
|
+
def validate_states(states)
|
171
|
+
states.each do |state|
|
172
|
+
unless state.is_a?(Hash) && state.key?(:name)
|
173
|
+
raise ArgumentError, "Invalid state: each state must be a hash with a 'name' key"
|
174
|
+
end
|
175
|
+
validate_state(state)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def validate_general_tool(tool)
|
180
|
+
case tool[:type]
|
181
|
+
when 'end_call', 'press_digit'
|
182
|
+
validate_tool_keys(tool, required: [:name, :type], optional: [:description])
|
183
|
+
when 'transfer_call'
|
184
|
+
validate_tool_keys(tool, required: [:name, :number, :type], optional: [:description])
|
185
|
+
when 'check_availability_cal', 'book_appointment_cal'
|
186
|
+
validate_tool_keys(tool, required: [:cal_api_key, :event_type_id, :name, :type], optional: [:description, :timezone])
|
187
|
+
when 'custom'
|
188
|
+
validate_custom_tool(tool)
|
189
|
+
else
|
190
|
+
raise ArgumentError, "Unknown general tool type: #{tool[:type]}"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def validate_custom_tool(tool)
|
195
|
+
validate_tool_keys(tool,
|
196
|
+
required: [:name, :type, :description, :url, :speak_after_execution, :speak_during_execution],
|
197
|
+
optional: [:execution_message_description, :timeout_ms, :parameters]
|
198
|
+
)
|
199
|
+
validate_custom_tool_parameters(tool[:parameters]) if tool[:parameters]
|
200
|
+
validate_timeout_ms(tool[:timeout_ms]) if tool[:timeout_ms]
|
201
|
+
end
|
202
|
+
|
203
|
+
def validate_timeout_ms(timeout_ms)
|
204
|
+
unless timeout_ms.is_a?(Integer) && timeout_ms >= 1000 && timeout_ms <= 600000
|
205
|
+
raise ArgumentError, "timeout_ms must be an integer between 1000 and 600000"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def validate_custom_tool_parameters(parameters)
|
210
|
+
validate_tool_keys(parameters, required: [:type, :properties], optional: [:required])
|
211
|
+
end
|
212
|
+
|
213
|
+
def validate_state(state)
|
214
|
+
validate_tool_keys(state, required: [:name], optional: [:edges, :state_prompt, :tools])
|
215
|
+
validate_general_tools(state[:tools]) if state[:tools]
|
216
|
+
validate_state_edges(state[:edges]) if state[:edges]
|
217
|
+
end
|
218
|
+
|
219
|
+
def validate_state_edges(edges)
|
220
|
+
edges.each { |edge| validate_state_edge(edge) }
|
221
|
+
end
|
222
|
+
|
223
|
+
def validate_state_edge(edge)
|
224
|
+
validate_tool_keys(edge,
|
225
|
+
required: [:description, :destination_state_name],
|
226
|
+
optional: [:parameters]
|
227
|
+
)
|
228
|
+
validate_state_edge_parameters(edge[:parameters]) if edge[:parameters]
|
229
|
+
end
|
230
|
+
|
231
|
+
def validate_state_edge_parameters(parameters)
|
232
|
+
validate_tool_keys(parameters, required: [:type, :properties], optional: [:required])
|
233
|
+
end
|
234
|
+
|
235
|
+
def validate_tool_keys(hash, required: [], optional: [])
|
236
|
+
missing_keys = required - hash.keys
|
237
|
+
if missing_keys.any?
|
238
|
+
raise ArgumentError, "Missing required keys: #{missing_keys.join(', ')}"
|
239
|
+
end
|
240
|
+
|
241
|
+
unexpected_keys = hash.keys - (required + optional)
|
242
|
+
if unexpected_keys.any?
|
243
|
+
raise ArgumentError, "Unexpected keys found: #{unexpected_keys.join(', ')}"
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def validate_non_empty_string(value, name)
|
248
|
+
raise ArgumentError, "#{name} cannot be empty" if value.empty?
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Retell
|
2
|
+
module SDK
|
3
|
+
module Unofficial
|
4
|
+
module API
|
5
|
+
class Voice
|
6
|
+
def initialize(client)
|
7
|
+
@client = client
|
8
|
+
end
|
9
|
+
|
10
|
+
def retrieve(
|
11
|
+
voice_or_id,
|
12
|
+
extra_headers: nil,
|
13
|
+
extra_query: nil,
|
14
|
+
extra_body: nil,
|
15
|
+
timeout: nil
|
16
|
+
)
|
17
|
+
voice_id = voice_or_id.is_a?(Retell::SDK::Unofficial::Voice) ? voice_or_id.voice_id : voice_or_id
|
18
|
+
|
19
|
+
raise ArgumentError, "Expected a non-empty value for `voice_id` but received #{voice_id.inspect}" if voice_id.to_s.empty?
|
20
|
+
|
21
|
+
options = @client.make_request_options(
|
22
|
+
extra_headers: extra_headers,
|
23
|
+
extra_query: extra_query,
|
24
|
+
extra_body: extra_body,
|
25
|
+
timeout: timeout
|
26
|
+
)
|
27
|
+
|
28
|
+
@client.get("/get-voice/#{voice_id}", **options)
|
29
|
+
end
|
30
|
+
|
31
|
+
def list(
|
32
|
+
extra_headers: nil,
|
33
|
+
extra_query: nil,
|
34
|
+
extra_body: nil,
|
35
|
+
timeout: nil
|
36
|
+
)
|
37
|
+
options = @client.make_request_options(
|
38
|
+
extra_headers: extra_headers,
|
39
|
+
extra_query: extra_query,
|
40
|
+
extra_body: extra_body,
|
41
|
+
timeout: timeout
|
42
|
+
)
|
43
|
+
|
44
|
+
@client.get('/list-voices', **options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Retell
|
2
|
+
module SDK
|
3
|
+
module Unofficial
|
4
|
+
class Base
|
5
|
+
class << self
|
6
|
+
attr_reader :attributes
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :client
|
10
|
+
|
11
|
+
def self.inherited(subclass)
|
12
|
+
subclass.instance_variable_set(:@attributes, [])
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.each_attribute
|
16
|
+
@attributes.each { |attr| yield attr }
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :changed_attributes
|
20
|
+
|
21
|
+
def self.writeable_attributes
|
22
|
+
@writeable_attributes ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(client, raw_response)
|
26
|
+
@client = client
|
27
|
+
@changed_attributes = {}
|
28
|
+
self.class.attributes.each do |attr|
|
29
|
+
instance_variable_set("@#{attr}", raw_response[attr])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def [](key)
|
34
|
+
send(key) if self.class.attributes.include?(key.to_sym)
|
35
|
+
end
|
36
|
+
|
37
|
+
def []=(key, value)
|
38
|
+
if self.class.writeable_attributes.include?(key.to_sym)
|
39
|
+
instance_variable_set("@#{key}", value)
|
40
|
+
@changed_attributes[key.to_sym] = value
|
41
|
+
else
|
42
|
+
raise KeyError, "key not found or not writable: #{key}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_h
|
47
|
+
self.class.attributes.each_with_object({}) do |attr, hash|
|
48
|
+
hash[attr] = send(attr)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def keys
|
53
|
+
self.class.attributes
|
54
|
+
end
|
55
|
+
|
56
|
+
def values
|
57
|
+
self.class.attributes.map { |attr| send(attr) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def each
|
61
|
+
if block_given?
|
62
|
+
to_h.each do |key, value|
|
63
|
+
yield(key, value)
|
64
|
+
end
|
65
|
+
to_h
|
66
|
+
else
|
67
|
+
to_enum(:each)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def fetch(key, default = nil)
|
72
|
+
if self.class.attributes.include?(key.to_sym)
|
73
|
+
send(key)
|
74
|
+
else
|
75
|
+
block_given? ? yield(key) : (default || raise(KeyError, "key not found: #{key}"))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module Retell
|
4
|
+
module SDK
|
5
|
+
module Unofficial
|
6
|
+
class BaseCall < Base
|
7
|
+
@attributes = [
|
8
|
+
:call_id, :agent_id, :call_status, :call_type,
|
9
|
+
:start_timestamp, :end_timestamp, :transcript, :recording_url,
|
10
|
+
:public_log_url, :call_analysis, :e2e_latency, :llm_latency,
|
11
|
+
:llm_websocket_network_rtt_latency, :transcript_object,
|
12
|
+
:transcript_with_tool_calls, :disconnection_reason, :metadata,
|
13
|
+
:retell_llm_dynamic_variables, :opt_out_sensitive_data_storage
|
14
|
+
]
|
15
|
+
|
16
|
+
attr_reader *@attributes
|
17
|
+
|
18
|
+
def id
|
19
|
+
call_id
|
20
|
+
end
|
21
|
+
|
22
|
+
def agent
|
23
|
+
agent_id
|
24
|
+
end
|
25
|
+
|
26
|
+
def status
|
27
|
+
call_status
|
28
|
+
end
|
29
|
+
|
30
|
+
def type
|
31
|
+
call_type
|
32
|
+
end
|
33
|
+
|
34
|
+
def analysis
|
35
|
+
call_analysis
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Retell
|
2
|
+
module SDK
|
3
|
+
module Unofficial
|
4
|
+
class BaseList
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
attr_reader :items
|
8
|
+
|
9
|
+
def initialize(items_key, raw_response)
|
10
|
+
@items = raw_response[items_key]
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](index)
|
14
|
+
@items[index]
|
15
|
+
end
|
16
|
+
|
17
|
+
def each
|
18
|
+
if block_given?
|
19
|
+
to_a.each do |value|
|
20
|
+
yield(value)
|
21
|
+
end
|
22
|
+
to_a
|
23
|
+
else
|
24
|
+
to_enum(:each)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def length
|
29
|
+
@items.length
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method :size, :length
|
33
|
+
|
34
|
+
def to_a
|
35
|
+
@items
|
36
|
+
end
|
37
|
+
|
38
|
+
def empty?
|
39
|
+
@items.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def first
|
43
|
+
@items.first
|
44
|
+
end
|
45
|
+
|
46
|
+
def last
|
47
|
+
@items.last
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Retell
|
2
|
+
module SDK
|
3
|
+
module Unofficial
|
4
|
+
class Call
|
5
|
+
def self.new(client, raw_response)
|
6
|
+
case raw_response[:call_type]
|
7
|
+
when 'web_call'
|
8
|
+
Retell::SDK::Unofficial::WebCall.new(client, raw_response)
|
9
|
+
when 'phone_call'
|
10
|
+
Retell::SDK::Unofficial::PhoneCall.new(client, raw_response)
|
11
|
+
else
|
12
|
+
raise ArgumentError, "Unknown call type: #{raw_response[:call_type]}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|