@@ -6,11 +6,21 @@ module Hellio
66 # session), rented extensions (the short codes subscribers dial), sessions, and
77 # a simulator for exercising an app's callback without a live dial.
88 #
9+ # Apps carry two modes, "test" and "live". A new app starts in "test" and
10+ # exposes both a `test_secret` (prefix "ussk_test_") and a `live_secret`
11+ # (prefix "ussk_live_"); `mode`/`is_live` say which one is active. Switching an
12+ # app to "live" requires a purchased USSD extension. Extension rentals draw
13+ # from a dedicated USSD balance, separate from SMS credit and the main wallet.
14+ #
915 # Requests are routed through the owning client, so responses are decoded to a
1016 # Hash with string keys (payloads under "data") and non-2xx responses raise the
1117 # same typed Hellio::Error subclasses. A rented-out extension returns 409
12- # (Hellio::ConflictError) and an underfunded account returns 402
13- # (Hellio::InsufficientBalanceError).
18+ # (Hellio::ConflictError), an underfunded USSD balance returns 402
19+ # (Hellio::InsufficientBalanceError, slug "insufficient_ussd_balance"), and
20+ # going live before an extension is purchased returns 402
21+ # (Hellio::ExtensionRequiredError, slug "extension_required").
22+ #
23+ # App and extension ids are UUID strings.
1424 class Ussd
1525 def initialize ( client )
1626 @client = client
@@ -37,14 +47,18 @@ def apps
3747 end
3848
3949 # Create a USSD app. `callback_url` is where Hellio POSTs each session step.
50+ # The returned "data" includes the app `id` (UUID string), `name`,
51+ # `callback_url`, `mode` ("test" by default), `test_secret` ("ussk_test_..."),
52+ # `live_secret` ("ussk_live_..."), `is_live`, and `active`.
4053 def create_app ( name :, callback_url :)
4154 post ( "ussd/apps" , compact (
4255 "name" => name ,
4356 "callback_url" => callback_url
4457 ) )
4558 end
4659
47- # Update a USSD app. Pass only the fields you want to change.
60+ # Update a USSD app (`id` is a UUID string). Pass only the fields you want to
61+ # change.
4862 def update_app ( id , name : nil , callback_url : nil , active : nil )
4963 put ( "ussd/apps/#{ id } " , compact (
5064 "name" => name ,
@@ -53,7 +67,21 @@ def update_app(id, name: nil, callback_url: nil, active: nil)
5367 ) )
5468 end
5569
56- # Delete a USSD app by id.
70+ # Switch a USSD app's mode (`id` is a UUID string; `mode` is "test" or
71+ # "live"). Returns the app. Switching to "live" before a USSD extension is
72+ # purchased raises Hellio::ExtensionRequiredError (402).
73+ def set_mode ( id , mode )
74+ post ( "ussd/apps/#{ id } /mode" , "mode" => mode )
75+ end
76+
77+ # Rotate a USSD app's secret for one mode (`id` is a UUID string; `mode` is
78+ # "test" or "live"). Returns the app with the freshly rotated secret. The old
79+ # secret for that mode stops working immediately.
80+ def rotate_secret ( id , mode )
81+ post ( "ussd/apps/#{ id } /rotate-secret" , "mode" => mode )
82+ end
83+
84+ # Delete a USSD app by id (UUID string).
5785 def delete_app ( id )
5886 delete ( "ussd/apps/#{ id } " )
5987 end
@@ -65,17 +93,19 @@ def extensions
6593 get ( "ussd/extensions" )
6694 end
6795
68- # Rent an extension by code, optionally attaching it to an app. Raises
96+ # Rent an extension by code, optionally attaching it to an app (`app_id` is a
97+ # UUID string). Rentals draw from the dedicated USSD balance. Raises
6998 # Hellio::ConflictError (409) if the code is no longer available and
70- # Hellio::InsufficientBalanceError (402) if the balance is too low.
99+ # Hellio::InsufficientBalanceError (402, slug "insufficient_ussd_balance") if
100+ # the USSD balance is too low.
71101 def rent_extension ( code , app_id : nil )
72102 post ( "ussd/extensions" , compact (
73103 "code" => code ,
74104 "app_id" => app_id
75105 ) )
76106 end
77107
78- # Release a rented extension by id.
108+ # Release a rented extension by id (UUID string) .
79109 def release_extension ( id )
80110 delete ( "ussd/extensions/#{ id } " )
81111 end
@@ -87,24 +117,29 @@ def sessions(status: nil)
87117 get ( "ussd/sessions" , compact ( "status" => status ) )
88118 end
89119
90- # Fetch a single session by id.
120+ # Fetch a single session by id (UUID string) .
91121 def session ( id )
92122 get ( "ussd/sessions/#{ id } " )
93123 end
94124
95125 # -------------------------------------------------------------- Simulator
96126
97- # Simulate a USSD step against an app's callback. Pass `new_session: true`
98- # for the first step (dialing the code) and the returned `session_id` on
99- # follow-up steps. Returns the app's reply plus the `action` ("continue" or
127+ # Simulate a USSD step against an app's callback. `app_id` (UUID string) is
128+ # the app to drive. Pass `new_session: true` for the first step (dialing the
129+ # code) and reuse the same `session_id` on follow-up steps. `service_code` is
130+ # optional and defaults server-side to the shared short code; pass it only to
131+ # override. Simulation is always sandboxed (no charge, no extension needed).
132+ # A not-owned `app_id` raises Hellio::ValidationError (422, slug
133+ # "unknown_app"). Returns the app's reply plus the `action` ("continue" or
100134 # "end").
101- def simulate ( msisdn :, service_code :, input : nil , session_id : nil , new_session : nil )
135+ def simulate ( app_id :, session_id :, msisdn : , input : "" , new_session : false , service_code : nil )
102136 post ( "ussd/simulate" , compact (
137+ "app_id" => app_id ,
103138 "session_id" => session_id ,
104139 "msisdn" => msisdn ,
105- "service_code" => service_code ,
106140 "input" => input ,
107- "new_session" => new_session
141+ "new_session" => new_session ,
142+ "service_code" => service_code
108143 ) )
109144 end
110145
0 commit comments